Oracle
 sql >> Base de données >  >> RDS >> Oracle

Analyser les noms de table à partir d'un tas d'instructions SQL

Si c'était moi, j'aurais tendance à essayer d'aborder le problème d'une manière différente. Plutôt que d'écrire un analyseur SQL (ce qui nécessiterait bien plus qu'une expression régulière à moins que vous ne puissiez garantir que toutes les instructions SQL utilisent un tout petit sous-ensemble de la grammaire SQL disponible), j'aurais tendance à générer un plan de requête pour chaque objet, puis requête PLAN_TABLE pour voir les objets qu'Oracle doit frapper. Vous auriez besoin de faire une recherche supplémentaire pour les accès à l'index pour savoir sur quelle table l'index est défini, mais cela devrait être raisonnablement simple.

Si vous suivez cette voie, cependant, vous récupérerez les tables de base auxquelles votre requête touche réellement plutôt que les vues auxquelles les requêtes peuvent réellement faire référence. Autrement dit, si vous avez une requête SELECT * FROM view_1 et view_1 , à son tour, est défini comme une requête sur table_a et table_b , uniquement table_a et table_b fera partie du plan. Et vous auriez besoin de désactiver query_rewrite pour la session si vous vouliez empêcher les plans de requête de référencer des vues matérialisées si ces vues matérialisées ne faisaient pas spécifiquement partie de la requête.

Si, pour chaque requête, vous effectuez une

EXPLAIN PLAN FOR <<the query>>

vous pouvez alors

SELECT DISTINCT object_owner, object_name, object_type
  FROM plan_table

pour obtenir la liste des objets. Si OBJECT_TYPE est comme INDEX% , vous pouvez alors utiliser le DBA_INDEXES afficher (ou ALL_INDEXES ou USER_INDEXES en fonction du propriétaire des objets en question et de votre niveau de privilèges) pour déterminer sur quelle table cet index est défini

SELECT table_owner, table_name
  FROM dba_indexes
 WHERE owner = <<object_owner from plan_table>>
   AND index_name = <<object_name from plan_table>>

Ainsi, par exemple, si j'ai une vue view_1

 create or replace view view_1
 as
 select *
   from emp join dept using (deptno)

et une requête

select * from view_1;

je peux faire

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

Cela me dit que la requête touche en fait le EMP et DEPT les tables. Il frappe également le PK_DEPT index afin que je puisse regarder pour voir sur quelle table cela est défini.

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

Il s'avère que cet index est défini sur le DEPT table également, donc je sais que seul le EMP et DEPT tableaux dans le SCOTT schéma va être impliqué dans la requête.