可以使用DBMS_UTILITY.EXPAND_SQL_TEXT、临时视图和查询DBA_DEPENDENCIES生成SQL语句使用的表列表。
DBMS_UTILITY.EXPAND_SQL_TEXT 负责查找视图引用的表。临时视图和DBA_DEPENDENCIES 然后生成扩展 SQL 语句中使用的所有表的列表。
功能
create or replace function get_dependent_tables_from_sql(p_sql varchar2)
return sys.odcivarchar2list authid current_user is
v_expanded_sql clob;
v_tables sys.odcivarchar2list := sys.odcivarchar2list();
pragma autonomous_transaction;
begin
--Expand the SQL, which will go through all the recursive dependencies.
dbms_utility.expand_sql_text
(
input_sql_text => p_sql,
output_sql_text => v_expanded_sql
);
--Create a view with the expanded SQL.
execute immediate
'
create or replace view temp_view_for_dependencies as
select count(*) the_count
from
(
'||v_expanded_sql||'
)
';
--Find dependencies.
--(Use execute immediate to simplify compilation privileges.)
execute immediate
q'[
select distinct referenced_owner||'.'||referenced_name
from dba_dependencies
where name = 'TEMP_VIEW_FOR_DEPENDENCIES'
and owner = user
and referenced_type = 'TABLE'
]'
bulk collect into v_tables;
return v_tables;
end get_dependent_tables_from_sql;
/
示例架构
create table table1(col1 number, col2 number);
create table table2(col1 number, col2 number);
create table table3(col1 number, col2 number);
create table table4(col1 number, col2 number);
create table table5(col1 number, col2 number);
create or replace view view1 as select 1 a from dual;
调用函数
select column_value table_name
from table(get_dependent_tables_from_sql(q'[
select *
from table1 t1
--ANSI joins
join table2 t2
on t1.col1 = t2.col1
where exists
(
select 1
--Oracle style joins, views.
from table3 t3, table4, view1
where t1.col2 = t3.col2
)
--A table that won't be in execution plan.
and exists (select 1 from table5 where 1 = 2)
]'))
order by 1;
TABLE_NAME
----------
JHELLER.TABLE1
JHELLER.TABLE2
JHELLER.TABLE3
JHELLER.TABLE4
JHELLER.TABLE5
SYS.DUAL
关于其他解决方案的警告
小心涉及自定义 SQL 解析的解决方案。这是看起来非常容易的问题之一。您可以构建一个 98% 的时间都有效的正则表达式,但实际上不可能构建一个 100% 的时间有效的正则表达式。
谨慎使用执行计划解决方案。将执行计划对象追溯到表并非易事,就像只使用索引一样。并且某些表可以在查询中使用,但由于连接消除而被排除在执行计划之外。