Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Analise os nomes das tabelas de várias instruções SQL


Se fosse eu, tenderia a tentar abordar o problema de uma maneira diferente. Em vez de escrever um analisador SQL (que exigiria muito mais do que uma expressão regular, a menos que você possa garantir que todas as instruções SQL usem um subconjunto muito pequeno da gramática SQL disponível), eu tenderia a gerar um plano de consulta para cada objeto e, em seguida, consulta PLAN_TABLE para ver os objetos que o Oracle tem que acertar. Você precisaria fazer uma pesquisa adicional para acessos de índice para descobrir em qual tabela o índice está definido, mas isso deve ser razoavelmente simples.

Se você seguir esse caminho, no entanto, estará recuperando as tabelas base que sua consulta realmente toca, em vez de quaisquer visualizações às quais as consultas possam realmente se referir. Ou seja, se você tiver uma consulta SELECT * FROM view_1 e view_1 , por sua vez, é definido como uma consulta em table_a e table_b , apenas table_a e table_b fará parte do plano. E você precisaria desabilitar query_rewrite para a sessão se você quiser impedir que os planos de consulta façam referência a visualizações materializadas se essas visualizações materializadas não fizerem parte especificamente da consulta.

Se, para cada consulta, você fizer uma
EXPLAIN PLAN FOR <<the query>>

você pode então
SELECT DISTINCT object_owner, object_name, object_type
  FROM plan_table

para obter a lista de objetos. Se OBJECT_TYPE é como INDEX% , você pode usar o DBA_INDEXES visualização (ou ALL_INDEXES ou USER_INDEXES dependendo de quem possui os objetos em questão e qual nível de privilégios você tem) para determinar em qual tabela esse índice está definido
SELECT table_owner, table_name
  FROM dba_indexes
 WHERE owner = <<object_owner from plan_table>>
   AND index_name = <<object_name from plan_table>>

Então, por exemplo, se eu tiver uma visão view_1
 create or replace view view_1
 as
 select *
   from emp join dept using (deptno)

e uma consulta
select * from view_1;

eu posso fazer
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

Isso me diz que a consulta está realmente atingindo o EMP e DEPT mesas. Também está atingindo o PK_DEPT index para que eu possa ver em qual tabela 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

Como se vê, esse índice é definido no DEPT tabela também, então eu sei que apenas o EMP e DEPT tabelas no SCOTT esquema vão estar envolvidos na consulta.