需要一个查询来从所有表/视图中搜索一个值(“数字”)
Posted
技术标签:
【中文标题】需要一个查询来从所有表/视图中搜索一个值(“数字”)【英文标题】:Need a Query to search a value("Number") from all tables/views 【发布时间】:2015-08-26 12:18:08 【问题描述】:我使用 Oracle 11G 数据库并在 Toad 中工作。我需要一个查询来在所有表和视图中搜索一个数字(9901)。我找到了一些 PL/SQL 代码,但它们适用于字符串。我有关于 SQL 的知识,但我不知道 PL/SQL。我的用户是 SYS,我想我有权进行这样的查询。你能帮忙处理这个案子吗?
【问题讨论】:
如果你想查询它,你想要什么作为查询的返回值? 我想查看所有包含 number(9901) 的列和表/视图名称。 查看***.com/questions/208493/… 【参考方案1】:如果您想搜索表/列的名称或表中包含的实际值,我没有收集。
在前一种情况下,您的目标可以通过一个简单的查询来实现(将过滤器中的值替换为正确的值(但保留 % 符号)):
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 数据类型。
重要提示! - 如果您的数据库中有很多/大型表,这将运行非常缓慢并且可能会给系统带来高负载。毕竟会涉及到多次全表扫描。
对于视图,您需要检查报告表上每个视图的代码,并检查它是否包含任何报告列。
【讨论】:
ORA-06550:第 14 行,第 14 列:PL/SQL:ORA-00942:表或视图不存在 ORA-06550:第 13 行,第 9 列:PL/SQL:SQL 语句被忽略 ORA -06550:第 28 行,第 34 列:PLS-00364:循环索引变量“V_TAB_ROW”使用无效 ORA-06550:第 28 行,第 34 列:PL/SQL:ORA-00904:“V_TAB_ROW”。“TABLE_NAME”:geçersiz belirleyici ORA-06550:第 24 行,第 13 列:PL/SQL:SQL 语句被忽略 ORA-06550:第 31 行,第 37 列:它给出了这样的错误。我不知道原因。我更改了架构名称。 而且我不是在搜索列名或表名。我正在搜索值 9901,即在表/视图的记录中。 很可能您在字典视图 dba_tab_columns 上没有选择权限。如果您以要在其中执行搜索的表的所有者身份登录,请将其替换为 user_tab_columns 忘了提到 user_tab_columns 没有“所有者”列,因为那里描述的所有对象都是当前用户的财产。 all_tab_columns 包含有关所有当前可访问对象的信息,因此有一个“所有者”列。以上是关于需要一个查询来从所有表/视图中搜索一个值(“数字”)的主要内容,如果未能解决你的问题,请参考以下文章