sql >> Base de Datos >  >> RDS >> Oracle

Analizar nombres de tablas de un montón de sentencias SQL

Si fuera yo, tendería a tratar de abordar el problema de una manera diferente. En lugar de escribir un analizador de SQL (que requeriría mucho más que una expresión regular, a menos que pueda garantizar que todas las declaraciones de SQL usen un subconjunto muy pequeño de la gramática de SQL disponible), tendería a generar un plan de consulta para cada objeto y luego consulta PLAN_TABLE para ver los objetos que Oracle tiene que golpear. Debería realizar una búsqueda adicional de accesos de índice para averiguar en qué tabla está definido el índice, pero eso debería ser razonablemente sencillo.

Sin embargo, si sigue este camino, recuperará las tablas base a las que realmente toca su consulta en lugar de las vistas a las que realmente se refieren las consultas. Es decir, si tiene una consulta SELECT * FROM view_1 y view_1 , a su vez, se define como una consulta contra table_a y table_b , solo table_a y table_b será parte del plan. Y necesitaría deshabilitar query_rewrite para la sesión si quería evitar que los planes de consulta hicieran referencia a vistas materializadas si esas vistas materializadas no formaban parte específica de la consulta.

Si, para cada consulta, haces un

EXPLAIN PLAN FOR <<the query>>

entonces puedes

SELECT DISTINCT object_owner, object_name, object_type
  FROM plan_table

para obtener la lista de objetos. Si OBJECT_TYPE es como INDEX% , luego puede usar el DBA_INDEXES ver (o ALL_INDEXES o USER_INDEXES dependiendo de quién es el propietario de los objetos en cuestión y qué nivel de privilegios tiene) para determinar en qué tabla está definido ese índice

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

Entonces, por ejemplo, si tengo una vista view_1

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

y una consulta

select * from view_1;

Puedo hacer

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

Esto me dice que la consulta en realidad está presionando el EMP y DEPT mesas. También está golpeando el PK_DEPT index para que pueda ver en qué tabla está definida.

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

Resulta que ese índice está definido en el DEPT tabla también, así que sé que solo el EMP y DEPT tablas en el SCOTT el esquema va a estar involucrado en la consulta.