-2

我在一个名为 Queries 的列中有一个包含数千条 SQL 语句的表。关于如何使用正则表达式从语句中获取表名的任何想法?

4

1 回答 1

8

如果是我,我会倾向于尝试以不同的方式解决问题。我倾向于为每个对象生成一个查询计划,而不是编写一个 SQL 解析器(这将需要比正则表达式更多的东西,除非你可以保证所有 SQL 语句都使用可用 SQL 语法的一个非常小的子集)。查询PLAN_TABLE以查看 Oracle 必须命中的对象。您需要对索引访问进行额外的查找,以找出索引是在哪个表上定义的,但这应该相当简单。

但是,如果您沿着这条路走,您将检索查询实际触及的基表,而不是查询可能实际引用的任何视图。也就是说,如果您有一个查询SELECT * FROM view_1view_1而 又被定义为针对table_aand的查询table_b,那么只有table_aandtable_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_INDEXESUSER_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

这告诉我查询实际上是在访问EMPandDEPT表。它也命中了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表上定义,所以我知道只有模式中的EMPDEPTSCOTT将参与查询。

于 2012-11-13T18:54:20.893 回答