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.