Om det var jag skulle jag ha en tendens att försöka närma mig problemet på ett annat sätt. Istället för att skriva en SQL-parser (som skulle kräva mycket mer än ett reguljärt uttryck om du inte kan garantera att alla SQL-satser använder en mycket liten delmängd av den tillgängliga SQL-grammatiken), skulle jag tendera att generera en frågeplan för varje objekt och sedan fråga PLAN_TABLE
för att se objekten som Oracle måste träffa. Du skulle behöva göra en extra sökning efter indexåtkomster för att ta reda på vilken tabell indexet är definierat på, men det borde vara ganska okomplicerat.
Om du går på den här vägen kommer du dock att hämta bastabellerna som din fråga faktiskt berör snarare än vilka vyer som frågorna faktiskt refererar till. Det vill säga om du har en fråga SELECT * FROM view_1
och view_1
, i sin tur, definieras som en fråga mot table_a
och table_b
, endast table_a
och table_b
kommer att vara en del av planen. Och du skulle behöva inaktivera query_rewrite
för sessionen om du ville förhindra att frågeplanerna hänvisar till materialiserade vyer om dessa materialiserade vyer inte specifikt var en del av frågan.
Om du för varje fråga gör en
EXPLAIN PLAN FOR <<the query>>
du kan sedan
SELECT DISTINCT object_owner, object_name, object_type
FROM plan_table
för att få listan över objekt. Om OBJECT_TYPE
är som INDEX%
, kan du sedan använda DBA_INDEXES
vy (eller ALL_INDEXES
eller USER_INDEXES
beroende på vem som äger objekten i fråga och vilken nivå av privilegier du har) för att avgöra vilken tabell det indexet är definierat på
SELECT table_owner, table_name
FROM dba_indexes
WHERE owner = <<object_owner from plan_table>>
AND index_name = <<object_name from plan_table>>
Så, till exempel, om jag har en vy view_1
create or replace view view_1
as
select *
from emp join dept using (deptno)
och en fråga
select * from view_1;
Jag kan göra
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
Detta säger mig att frågan faktiskt träffar EMP
och DEPT
tabeller. Den träffar också PK_DEPT
index så jag kan titta för att se vilken tabell som är definierad på.
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
Som det visar sig är det indexet definierat på DEPT
tabellen också, så jag vet att endast EMP
och DEPT
tabeller i SCOTT
schema kommer att vara involverade i frågan.