Oracle
 sql >> Database >  >> RDS >> Oracle

Analizza i nomi delle tabelle da un gruppo di istruzioni SQL

Se fossi in me, tenderei a cercare di affrontare il problema in un modo diverso. Piuttosto che scrivere un parser SQL (che richiederebbe molto più di un'espressione regolare a meno che tu non possa garantire che tutte le istruzioni SQL utilizzino un sottoinsieme molto piccolo della grammatica SQL disponibile), tenderei a generare un piano di query per ogni oggetto e quindi interrogare PLAN_TABLE per vedere gli oggetti che Oracle deve colpire. Dovresti eseguire un'ulteriore ricerca per gli accessi all'indice per scoprire su quale tabella è definito l'indice, ma dovrebbe essere ragionevolmente semplice.

Se segui questo percorso, tuttavia, recupererai le tabelle di base che la tua query tocca effettivamente piuttosto che le viste a cui le query potrebbero effettivamente fare riferimento. Cioè, se hai una query SELECT * FROM view_1 e view_1 , a sua volta, è definito come una query su table_a e table_b , solo table_a e table_b farà parte del piano. E dovresti disabilitare query_rewrite per la sessione se si desidera impedire ai piani di query di fare riferimento a viste materializzate se tali viste materializzate non facevano specificamente parte della query.

Se, per ogni query, esegui un

EXPLAIN PLAN FOR <<the query>>

puoi quindi

SELECT DISTINCT object_owner, object_name, object_type
  FROM plan_table

per ottenere l'elenco degli oggetti. Se OBJECT_TYPE è come INDEX% , puoi quindi utilizzare il DBA_INDEXES visualizza (o ALL_INDEXES o USER_INDEXES a seconda di chi possiede gli oggetti in questione e del livello di privilegi che hai) per determinare su quale tabella è definito quell'indice

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

Quindi, ad esempio, se ho una vista view_1

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

e una domanda

select * from view_1;

posso fare

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

Questo mi dice che la query sta effettivamente colpendo l'EMP e DEPT tavoli. Sta anche colpendo il PK_DEPT index così posso guardare per vedere su quale tabella è definita.

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

A quanto pare, quell'indice è definito su DEPT anche la tabella, quindi so che solo EMP e DEPT tabelle nel SCOTT lo schema saranno coinvolti nella query.