You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从V$SQL中提取SQL连接语句引用的所有表或视图?

从V$SQL的SQL语句中批量提取JOIN子句关联的表/视图

需求与示例

需从V$SQL中提取SQL语句所有JOIN子句里引用的表或视图:

示例SQL(来自V$SQL)

select * from ADANPT 
join BTABP on column1=column2 
left outer join HSTUDI on column3=column4
full outer join TERW on column5=column6;

目标提取结果

BTABP
HSTUDI
TERW

问题

单条JOIN时,可使用substr和instr函数提取JOIN至ON之间的字符串,但多条JOIN时不知如何实现,是否需要使用循环?

解决方案:无需显式循环,用正则表达式+层级查询实现

在Oracle中,不需要编写PL/SQL循环,直接用正则表达式结合CONNECT BY层级查询就能批量提取所有JOIN子句中的表/视图,示例如下:

-- 模拟V$SQL中的SQL语句,实际使用时替换为V$SQL的查询
WITH sql_source AS (
    SELECT 'select * from ADANPT 
join BTABP on column1=column2 
left outer join HSTUDI on column3=column4
full outer join TERW on column5=column6;' AS sql_text FROM dual
)
SELECT TRIM(REGEXP_SUBSTR(sql_text, '(LEFT OUTER JOIN|RIGHT OUTER JOIN|FULL OUTER JOIN|JOIN)\s+(\w+)', 1, LEVEL, 'i', 2)) AS joined_table
FROM sql_source
CONNECT BY LEVEL <= REGEXP_COUNT(sql_text, '(LEFT OUTER JOIN|RIGHT OUTER JOIN|FULL OUTER JOIN|JOIN)\s+\w+', 1, 'i');

语句说明

  1. REGEXP_COUNT:统计SQL中所有JOIN子句的数量,以此确定层级查询的遍历次数
  2. REGEXP_SUBSTR:
    • 第5个参数'i'表示忽略大小写,兼容Join、LEFT outer JOIN等大小写不规范的写法
    • 第6个参数2表示提取正则表达式中第二个捕获组的内容,也就是JOIN关键字后的表/视图名称
  3. TRIM:去除表名前后可能存在的空格
  4. CONNECT BY:替代显式循环,自动遍历所有JOIN子句

扩展适配

如果SQL中存在带引号的表名(如"BTABP"),可以调整正则表达式,将(\w+)替换为(["]?\w+["]?),兼容带引号的标识符。

实际对接V$SQL时,直接将sql_source替换为V$SQL的查询即可,例如:

SELECT TRIM(REGEXP_SUBSTR(sql_text, '(LEFT OUTER JOIN|RIGHT OUTER JOIN|FULL OUTER JOIN|JOIN)\s+(\w+)', 1, LEVEL, 'i', 2)) AS joined_table
FROM V$SQL
WHERE sql_id = '你的SQL_ID' -- 根据实际条件过滤
CONNECT BY LEVEL <= REGEXP_COUNT(sql_text, '(LEFT OUTER JOIN|RIGHT OUTER JOIN|FULL OUTER JOIN|JOIN)\s+\w+', 1, 'i')
AND PRIOR sql_id = sql_id
AND PRIOR SYS_GUID() IS NOT NULL; -- 避免层级查询出现笛卡尔积

内容的提问来源于stack exchange,提问作者Sara_Marp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 08:27:39