需要一个查询来从所有表/视图中搜索值(" Number")

时间:2015-08-26 12:18:08

标签: oracle plsql numbers views

我使用Oracle 11G数据库并在Toad中工作。我需要一个查询来搜索所有表和视图中的数字(9901)。我发现了一些PL / SQL代码,但它们正在为字符串工作。我对SQL有所了解,但我不懂PL / SQL。我的用户是SYS,我想我有权进行这样的查询。你能为这个案子提供帮助吗?

1 个答案:

答案 0 :(得分:0)

如果您想搜索表格/列的名称或表格中包含的实际值,我没有收集。

在前一种情况下,您的目标可以通过简单的查询来完成(将过滤器中的值替换为正确的值(但保留%符号)):

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>%' );

搜索实际的表数据有点复杂...... 以下是执行此类搜索的示例计划:

  1. 缩小搜索范围 - 按表所有者过滤(您真的不想在SYS或SYSTEM表中搜索...)
  2. 确定潜在的匹配候选者 - 在我们的案例中有数字列的表,因为我们正在搜索数字
  3. 检查每个表格中是否包含所需的值
  4. 找出包含所需值的确切列
  5. 以下是一个示例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数据类型。

    重要提示! - 如果您的数据库中有许多/大型表,则运行速度非常慢,可能会对系统造成很大负担。毕竟,将涉及多个全表扫描。

    对于视图,您需要检查报告表上每个视图的代码,并检查它是否包含任何报告的列。