Gdybym to ja, próbowałbym podejść do problemu w inny sposób. Zamiast pisać parser SQL (który wymagałby znacznie więcej niż wyrażenia regularnego, chyba że możesz zagwarantować, że wszystkie instrukcje SQL będą używać bardzo małego podzbioru dostępnej gramatyki SQL), mam tendencję do generowania planu zapytania dla każdego obiektu, a następnie zapytanie PLAN_TABLE
aby zobaczyć obiekty, w które Oracle ma trafić. Będziesz musiał przeprowadzić dodatkowe wyszukiwanie dostępu do indeksu, aby dowiedzieć się, na której tabeli zdefiniowany jest indeks, ale powinno to być dość proste.
Jeśli jednak pójdziesz tą ścieżką, będziesz pobierać tabele podstawowe, których faktycznie dotyczy zapytanie, a nie widoki, do których mogą się odwoływać zapytania. To znaczy, jeśli masz zapytanie SELECT * FROM view_1
i view_1
z kolei jest zdefiniowane jako zapytanie do table_a
i table_b
, tylko table_a
i table_b
będzie częścią planu. I musiałbyś wyłączyć query_rewrite
na sesję, jeśli chcesz uniemożliwić planom zapytań odwoływanie się do widoków zmaterializowanych, jeśli te widoki zmaterializowane nie są konkretną częścią zapytania.
Jeśli dla każdego zapytania wykonasz
EXPLAIN PLAN FOR <<the query>>
możesz wtedy
SELECT DISTINCT object_owner, object_name, object_type
FROM plan_table
aby uzyskać listę obiektów. Jeśli OBJECT_TYPE
jest jak INDEX%
, możesz użyć DBA_INDEXES
widok (lub ALL_INDEXES
lub USER_INDEXES
w zależności od tego, kto jest właścicielem danych obiektów i jakie masz uprawnienia), aby określić, w której tabeli zdefiniowany jest indeks
SELECT table_owner, table_name
FROM dba_indexes
WHERE owner = <<object_owner from plan_table>>
AND index_name = <<object_name from plan_table>>
Na przykład, jeśli mam widok view_1
create or replace view view_1
as
select *
from emp join dept using (deptno)
i zapytanie
select * from view_1;
mogę zrobić
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
To mówi mi, że zapytanie faktycznie trafia w EMP
i DEPT
tabele. Uderza również w PK_DEPT
indeks, dzięki czemu mogę sprawdzić, na której tabeli jest zdefiniowana.
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
Jak się okazuje, indeks ten jest zdefiniowany w DEPT
również tabelę, więc wiem, że tylko EMP
i DEPT
tabele w SCOTT
schemat będzie zaangażowany w zapytanie.