クエリと呼ばれる列に数千の SQL ステートメントを含むテーブルがあります。正規表現を使用してステートメントからテーブル名だけを取得する方法についてのアイデアはありますか?
1 に答える
私だったら、別の方法で問題にアプローチしようとする傾向があります。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のみがクエリに関与することがわかっています。EMPDEPTSCOTT