如果您想搜索表/列的名称或表中包含的实际值,我没有收集。
在前一种情况下,您的目标可以通过一个简单的查询来实现(将过滤器中的值替换为正确的值(但保留 % 符号)):
select
owner,
table_name,
column_name
from
dba_tab_columns
where
owner = '<TABLE_OWNER>'
and ( table_name like '%<SEARCH_VALUE>%'
or column_name like '%<SEARCH_VALUE>%' );
搜索实际的表数据有点复杂...
以下是执行此类搜索的示例计划:
- 缩小搜索范围 - 按表所有者过滤(您确实不想在 SYS 或 SYSTEM 表中搜索...)
- 识别潜在的匹配候选者 - 在我们的案例中,表格包含数字列,因为我们正在搜索数字
- 检查每个表中是否有所需的值
- 找出包含所需值的确切列
这是一个示例 PL/SQL 脚本,它执行搜索并打印表名和列名(将 _SCHEMA_NAME_ 更改为正确的值):
declare
v_owner varchar2( 30 ) := '_SCHEMA_NAME_';
v_search_value number := 9901;
v_query_template varchar2( 500 ) := 'select ''x'' from dual where exists ( select 1 from <OWNER>.<TABLE> where <FILTER> )';
v_filter clob;
v_query clob;
v_match char(1);
begin
-- loop through all tables which are potential candidates - have numeric columns
for v_tab_row in
(
select distinct owner, table_name
from dba_tab_columns
where
owner = v_owner
and data_type in ( 'NUMBER', 'FLOAT' )
) loop
v_filter := '';
-- loop through each table column in order to build general match query
for v_col_row in
(
select owner, table_name, column_name
from dba_tab_columns
where
owner = v_tab_row.owner
and table_name = v_tab_row.table_name
and data_type in ( 'NUMBER', 'FLOAT' )
) loop
v_filter := v_filter || v_col_row.column_name || ' = ' || v_search_value || ' or ';
end loop;
v_filter := rtrim( v_filter, ' or ' );
v_query := replace( v_query_template, '<OWNER>', v_owner );
v_query := replace( v_query, '<TABLE>', v_tab_row.table_name );
v_query := replace( v_query, '<FILTER>', v_filter );
-- debug output:
--dbms_output.put_line( v_query );
begin
-- check if the table contains the search value anywhere in it
-- if not foung throws NO_DATA_FOUND exception and the loop continues
execute immediate v_query into v_match;
-- print the table name
dbms_output.put_line( v_tab_row.owner || '.' || v_tab_row.table_name );
-- loop through each table column to check which one of them contains the desired value
for v_col_row in
(
select owner, table_name, column_name
from dba_tab_columns
where
owner = v_tab_row.owner
and table_name = v_tab_row.table_name
and data_type in ( 'NUMBER', 'FLOAT' )
) loop
begin
v_query := replace( v_query_template, '<OWNER>', v_owner );
v_query := replace( v_query, '<TABLE>', v_tab_row.table_name );
v_query := replace( v_query, '<FILTER>', v_col_row.column_name || ' = ' || v_search_value );
-- debug output:
--dbms_output.put_line( v_query );
-- check if the specific column contains the desired value
-- if not foung throws NO_DATA_FOUND exception and the loop continues
execute immediate v_query into v_match;
-- print the column name
dbms_output.put_line( v_col_row.owner || '.' || v_col_row.table_name || '.' || v_col_row.column_name );
exception
when NO_DATA_FOUND
then
-- do nothing
null;
end;
end loop;
exception
when NO_DATA_FOUND
then
-- do nothing
null;
end;
end loop;
end;
也可以轻松修改代码以执行文本搜索 - 只需在循环查询中包含 varchar2、nvarchar2、char 和 nchar 数据类型。
重要提示! - 如果您的数据库中有很多/大型表,这将运行非常缓慢并且可能会给系统带来高负载。毕竟会涉及到多次全表扫描。
对于视图,您需要检查报告表上每个视图的代码,并检查它是否包含任何报告列。