【问题标题】:Search In All Tables For A Value (Oracle)在所有表中搜索值 (Oracle)
【发布时间】:2020-08-21 20:59:20
【问题描述】:

是否可以扫描架构中的每个表以查找 Oracle 中的特定值? ,逻辑上的小变化,我需要在架构中搜索特定列(SAMPLE_ABC),以便我可以进一步研究所有表都在使用此列 SAMPLE_ABC 以便我可以找到所需的结果

基本上我正在搜索一个数字示例 column_name - value-12345

我已经尝试了以下,但它运行了很长时间.......,我尝试搜索选项,但我无法

SET SERVEROUTPUT ON SIZE 100000

    DECLARE
      match_count INTEGER;
    BEGIN
      FOR t IN (SELECT owner, table_name, column_name
                  FROM all_tab_columns
                  WHERE owner <> 'SYS' and data_type LIKE '%CHAR%') LOOP

        EXECUTE IMMEDIATE
          'SELECT COUNT(*) FROM ' || t.owner || '.' || t.table_name ||
          ' WHERE '||t.column_name||' = :1'
          INTO match_count
          USING '12345';

        IF match_count > 0 THEN
          dbms_output.put_line( t.table_name ||' '||t.column_name||' '||match_count );
        END IF;

      END LOOP;

    END;
    /

【问题讨论】:

  • 有没有可能,是的。实用吗,NO。为了有任何机会运行,您需要进一步限制模式列表。除了 SYS 之外,可能还有至少 10-15 个不包含用户数据的额外模式。
  • 假设您生成的大多数 SELECTs 无论如何都会是全表扫描,那么更改 PL/SQL 块的逻辑以生成一个 @ 可能会快得多每个表 987654324@(而不是每列一个),所以看起来像这样:SELECT COUNT(*) FROM t WHERE a=:1 or b=:1 or c=:1 or...;如果您需要有关列的详细信息,请将 COUNT(*) 更改为 SUM(CASE when a=:1 then 1 else 0) cnt_a, SUM(CASE when b=:1 then 1 else 0) cnt_b, ...
  • 你可以参考这个答案,其中一个表只搜索一次stackoverflow.com/a/9614022/1297792

标签: sql oracle oracle-sqldeveloper


【解决方案1】:

如果您不想计算 搜索字符串的出现次数,EXISTS 可能是更好的选择,因为它会在找到第一次出现后立即停止搜索表。所以,我建议这样的事情;看看有没有帮助。

SQL> declare
  2     match_count    integer;
  3     search_string  varchar2 (20) := 'MANAGER';
  4     l_str          varchar2 (1000);
  5  begin
  6     for t in (select owner, table_name, column_name
  7                 from all_tab_columns
  8                where     owner <> 'SYS'
  9                      and owner in ('SCOTT', 'MIKE')
 10                      and data_type like '%CHAR%')
 11     loop
 12        l_str :=
 13              'SELECT MAX(1) FROM '
 14           || t.owner
 15           || '.'
 16           || t.table_name
 17           || ' a'
 18           || '  WHERE EXISTS (SELECT NULL FROM '
 19           || t.owner
 20           || '.'
 21           || t.table_name
 22           || ' b'
 23           || '                WHERE b.'
 24           || t.column_name
 25           || ' = a.'
 26           || t.column_name
 27           || '                AND b.'
 28           || t.column_name
 29           || ' = :1'
 30           || ')';
 31
 32        execute immediate l_str into match_count using search_string;
 33
 34        if match_count > 0
 35        then
 36           dbms_output.put_line (
 37              t.table_name || '.' || t.column_name || ' contains "' || search_string || '"');
 38        end if;
 39     end loop;
 40  end;
 41  /
EMP.JOB contains "MANAGER"

PL/SQL procedure successfully completed.

SQL>

【讨论】:

  • 我需要从您提到的 data_type 代码中搜索一个数值,例如 '%CHAR%'
  • 我从您的代码中复制了该部分,并与问题一起发布。
  • 我已经试过你的查询它根本没有停止,有没有办法增强?
  • 嗯,您正在搜索所有可用的表,所以... 承诺 会很慢。你能进一步限制你搜索的用户数量吗?目前,您仅省略 SYS。查看select distinct owner from all_tables 返回的内容是删除您不感兴趣的其他用户。例如,对我来说,它返回的用户为 APEX_040000、MDSYS、CTXSYS 等,我当然不希望找到例如国王在里面。
猜你喜欢
  • 2021-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-23
  • 1970-01-01
相关资源
最近更新 更多