それが私だったら、私は別の方法で問題にアプローチしようとする傾向がありました。 SQLパーサーを作成するのではなく(使用可能なSQL文法の非常に小さなサブセットを使用するすべてのSQLステートメントを保証できない限り、正規表現よりもはるかに多くのことが必要になります)、各オブジェクトのクエリプランを生成してから生成する傾向があります。クエリPLAN_TABLE
Oracleがヒットする必要のあるオブジェクトを確認します。インデックスが定義されているテーブルを見つけるには、インデックスアクセスの追加のルックアップを実行する必要がありますが、それはかなり簡単なはずです。
ただし、このパスをたどると、クエリが実際に参照する可能性のあるビューではなく、クエリが実際にアクセスするベーステーブルを取得することになります。つまり、クエリがSELECT * FROM view_1
の場合 およびview_1
次に、table_a
に対するクエリとして定義されます。 およびtable_b
、table_a
のみ および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
SCOTT
のテーブル スキーマがクエリに関与します。