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.