Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Przeanalizuj nazwy tabel z kilku instrukcji SQL

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.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Modelowanie Railsów:konwersja HABTM do has_many :through

  2. Jak uzyskać automatycznie zinkrementowany PK z bazy danych Oracle?

  3. jak korzystać z XMLImporter i FndXdfCmp w Oracle EBS

  4. ORA-01855:rano/po południu lub PM/PM. wymagany

  5. Czy można zabić pojedyncze zapytanie w Oracle bez zabijania sesji?