sql >> Databasteknik >  >> RDS >> Oracle

Analysera tabellnamn från ett gäng SQL-satser

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.




  1. Den lagrade proceduren för att hämta instansinställningarna

  2. Hur bearbetar man CSV med 100k+ rader i PHP?

  3. PHP\MYSQL förberedda uttalanden

  4. Lagring av mikrosekunder i MySQL:vilken lösning?