Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Analysieren Sie Tabellennamen aus einer Reihe von SQL-Anweisungen

Wenn ich es wäre, würde ich versuchen, das Problem anders anzugehen. Anstatt einen SQL-Parser zu schreiben (der viel mehr als einen regulären Ausdruck erfordern würde, es sei denn, Sie können garantieren, dass alle SQL-Anweisungen eine sehr kleine Teilmenge der verfügbaren SQL-Grammatik verwenden), würde ich eher einen Abfrageplan für jedes Objekt generieren und dann PLAN_TABLE abfragen um die Objekte zu sehen, die Oracle treffen muss. Sie müssten eine zusätzliche Suche nach Indexzugriffen durchführen, um herauszufinden, auf welcher Tabelle der Index definiert ist, aber das sollte ziemlich einfach sein.

Wenn Sie diesen Weg gehen, werden Sie jedoch die Basistabellen abrufen, die Ihre Abfrage tatsächlich berührt, und nicht die Ansichten, auf die sich die Abfragen möglicherweise tatsächlich beziehen. Das heißt, wenn Sie eine Abfrage haben SELECT * FROM view_1 und view_1 ist wiederum als Abfrage für table_a definiert und table_b , nur table_a und table_b wird Teil des Plans sein. Und Sie müssten query_rewrite deaktivieren für die Sitzung, wenn Sie verhindern wollten, dass die Abfragepläne auf materialisierte Ansichten verweisen, wenn diese materialisierten Ansichten nicht ausdrücklich Teil der Abfrage waren.

Wenn Sie für jede Abfrage eine

EXPLAIN PLAN FOR <<the query>>

Sie können dann

SELECT DISTINCT object_owner, object_name, object_type
  FROM plan_table

um die Liste der Objekte zu erhalten. Wenn OBJECT_TYPE ist wie INDEX% , können Sie dann die DBA_INDEXES verwenden Ansicht (oder ALL_INDEXES oder USER_INDEXES abhängig davon, wem die fraglichen Objekte gehören und welche Privilegien Sie haben), um festzustellen, in welcher Tabelle dieser Index definiert ist

SELECT table_owner, table_name
  FROM dba_indexes
 WHERE owner = <<object_owner from plan_table>>
   AND index_name = <<object_name from plan_table>>

Also zum Beispiel, wenn ich eine Ansicht view_1 habe

 create or replace view view_1
 as
 select *
   from emp join dept using (deptno)

und eine Abfrage

select * from view_1;

Ich kann

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

Dies sagt mir, dass die Abfrage tatsächlich den EMP trifft und DEPT Tische. Es trifft auch den PK_DEPT index, damit ich nachsehen kann, in welcher Tabelle das definiert ist.

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

Wie sich herausstellt, ist dieser Index auf DEPT definiert Tabelle auch, also kenne ich das nur vom EMP und DEPT Tabellen im SCOTT schema werden an der Abfrage beteiligt sein.