我在一个名为Queries的列中有一个包含数千个SQL语句的表。关于如何通过使用正则表达式从语句中获取表名的任何想法?
答案 0 :(得分:8)
如果是我,我倾向于尝试以不同的方式解决问题。而不是编写SQL解析器(除了可以保证所有SQL语句使用可用SQL语法的一个非常小的子集)之外,它需要的不仅仅是正则表达式,我倾向于为每个对象生成查询计划,然后查询PLAN_TABLE
以查看Oracle必须访问的对象。您需要对索引访问进行额外的查找,以找出索引定义的表,但这应该是相当简单的。
但是,如果沿着这条路走下去,那么您将检索查询实际触及的基表,而不是查询实际可能引用的任何视图。也就是说,如果您有一个查询SELECT * FROM view_1
而view_1
又被定义为针对table_a
和table_b
的查询,只有table_a
和{{ 1}}将成为计划的一部分。如果您希望阻止查询计划引用实体化视图(如果这些实体化视图不是查询的具体部分),则需要为会话禁用table_b
。
如果,对于每个查询,您执行
query_rewrite
然后你可以
EXPLAIN PLAN FOR <<the query>>
获取对象列表。如果SELECT DISTINCT object_owner, object_name, object_type
FROM plan_table
与OBJECT_TYPE
类似,则可以使用INDEX%
视图(或DBA_INDEXES
或ALL_INDEXES
,具体取决于拥有相关对象的人员以及您有权限)确定
USER_INDEXES
因此,例如,如果我有一个视图SELECT table_owner, table_name
FROM dba_indexes
WHERE owner = <<object_owner from plan_table>>
AND index_name = <<object_name from plan_table>>
view_1
和查询
create or replace view view_1
as
select *
from emp join dept using (deptno)
我能做到
select * from view_1;
这告诉我该查询实际上正在访问SQL> explain plan for select * from view_1;
Explained.
SQL> ed
Wrote file afiedt.buf
1 SELECT distinct object_owner, object_name, object_type
2* FROM plan_table
SQL> /
OBJECT_OWNER OBJECT_NAME OBJECT_TYPE
------------------------------ ------------------------- -------------------------
SCOTT DEPT TABLE
SCOTT PK_DEPT INDEX (UNIQUE)
SCOTT EMP TABLE
和EMP
表。它也在点击DEPT
索引,所以我可以查看定义的表。
PK_DEPT
事实证明,该索引也是在SQL> ed
Wrote file afiedt.buf
1 SELECT table_owner, table_name
2 FROM dba_indexes
3 WHERE owner = 'SCOTT'
4* AND index_name = 'PK_DEPT'
SQL> /
TABLE_OWNER TABLE_NAME
------------------------------ ------------------------------
SCOTT DEPT
表上定义的,所以我知道只有DEPT
模式中的EMP
和DEPT
表是将参与查询。