我在一个名为 Queries 的列中有一个包含数千条 SQL 语句的表。关于如何使用正则表达式从语句中获取表名的任何想法?
1 回答
如果是我,我会倾向于尝试以不同的方式解决问题。我倾向于为每个对象生成一个查询计划,而不是编写一个 SQL 解析器(这将需要比正则表达式更多的东西,除非你可以保证所有 SQL 语句都使用可用 SQL 语法的一个非常小的子集)。查询PLAN_TABLE
以查看 Oracle 必须命中的对象。您需要对索引访问进行额外的查找,以找出索引是在哪个表上定义的,但这应该相当简单。
但是,如果您沿着这条路走,您将检索查询实际触及的基表,而不是查询可能实际引用的任何视图。也就是说,如果您有一个查询SELECT * FROM view_1
,view_1
而 又被定义为针对table_a
and的查询table_b
,那么只有table_a
andtable_b
将成为计划的一部分。query_rewrite
如果您想阻止查询计划引用具体化视图(如果这些具体化视图不是查询的特定部分),则您需要为会话禁用。
如果,对于每个查询,你做一个
EXPLAIN PLAN FOR <<the query>>
然后你可以
SELECT DISTINCT object_owner, object_name, object_type
FROM plan_table
获取对象列表。如果OBJECT_TYPE
是 like 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
andDEPT
表。它也命中了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
表SCOTT
将参与查询。