查找Oracle中包含电子邮件的所有表和列

kuhbmx9i  于 2023-08-03  发布在  Oracle
关注(0)|答案(2)|浏览(116)

在我的Oracle数据库中,我有大约2K个表,我想找到其中包含电子邮件的表和列名。
条件:可能不是列名中有email标记,但列包含的值是<something>@<anything>.<tail>
从以前的类似线程的帮助下,它是运行没有任何输出

DECLARE
    l_cmd     VARCHAR2 (2000);
    l_found   INTEGER;
BEGIN
    FOR eachcol IN (  SELECT *
                        FROM all_tab_cols a
                       WHERE a.data_type = 'VARCHAR2'
                         AND owner = 'SEARCHSCHEMANAME'
                    ORDER BY table_name, column_name)
    LOOP
        l_cmd   :=
               'select count(*) c from '
            || eachcol.owner
            || '.'
            || eachcol.table_name
            || ' where '
            || LOWER (eachcol.column_name)
            || q'[ LIKE '%@%.%' AND ROWNUM = 1]';

        EXECUTE IMMEDIATE l_cmd INTO l_found;

        IF l_found > 0
        THEN
            DBMS_OUTPUT.put_line (
                   RPAD (eachcol.owner || '.' || eachcol.table_name || '.' || eachcol.column_name, 92)
                || ' may contain email addresses'
            );
        END IF;
    END LOOP;
EXCEPTION
    WHEN OTHERS
    THEN
        DBMS_OUTPUT.put_line (l_cmd);
        DBMS_OUTPUT.put_line (SQLERRM);
        RAISE;
END;

字符串
输出:

uqdfh47h

uqdfh47h1#

如果它不产生任何输出,则:

  • 没有包含此类数据的列
  • 也没有错误
  • 你忘记启用服务器输出

我稍微修改了你的代码

  • user_tab_cols中选择数据(不想尝试all_tab_cols
  • 包含内部BEGIN-EXCEPTION-END块,它处理可能的异常,但让循环继续(为什么我要在出错时停止执行?)不,我希望它继续)

它在我的模式中起作用,所以我认为它也应该在你的模式中起作用(除非你遇到我在开始时提到的三种可能性中的一种或多种)。

SQL> SET LINESIZE 200
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
  2     l_cmd    VARCHAR2 (2000);
  3     l_found  INTEGER;
  4  BEGIN
  5     FOR eachcol IN (  SELECT *
  6                         FROM user_tab_cols a
  7                        WHERE a.data_type = 'VARCHAR2'
  8                     --                         AND owner = 'SEARCHSCHEMANAME'
  9                     ORDER BY table_name, column_name)
 10     LOOP
 11        BEGIN
 12           l_cmd :=
 13                 'select count(*) c from '
 14              --            || eachcol.owner
 15              --            || '.'
 16              || eachcol.table_name
 17              || ' where '
 18              || '"' || eachcol.column_name || '"'
 19              || q'[ LIKE '%@%.%' AND ROWNUM = 1]';
 20
 21           EXECUTE IMMEDIATE l_cmd
 22              INTO l_found;
 23
 24           IF l_found > 0
 25           THEN
 26              DBMS_OUTPUT.put_line (
 27                    RPAD (                                         --eachcol.owner || '.' ||
 28                          eachcol.table_name || '.' || eachcol.column_name, 92)
 29                 || ' may contain email addresses');
 30           END IF;
 31        EXCEPTION
 32           WHEN OTHERS
 33           THEN
 34              DBMS_OUTPUT.put_line (l_cmd);
 35              DBMS_OUTPUT.put_line (SQLERRM);
 36        --RAISE;
 37        END;
 38     END LOOP;
 39  END;
 40  /

字符串
测试结果:

LOGS.LOG1                                                      may contain email addresses
OBR1_IN.E_MAIL                                                 may contain email addresses
OBR2_IN.E_MAIL                                                 may contain email addresses
...
RPRT_OP.E_MAIL                                                 may contain email addresses
RPRT_PO.E_MAIL                                                 may contain email addresses

PL/SQL procedure successfully completed.

SQL>

kknvjkwl

kknvjkwl2#

1.使用带引号的标识符来确保标识符的大小写正确(而不是使用LOWER和无引号的标识符,Oracle会隐式地将其转换回大写,这似乎毫无意义);
1.您还可以检查其他数据类型,包括CHARNVARCHAR2NCHAR;和/或
1.确保启用了DBMS_OUTPUT
就像这样:

DECLARE
  l_cmd   VARCHAR2 (2000);
  l_found INTEGER;
BEGIN
  DBMS_OUTPUT.ENABLE();
  FOR eachcol IN (
    SELECT owner,
           table_name,
           column_name
    FROM   all_tab_cols
    WHERE  data_type IN ('VARCHAR2', 'CHAR', 'NVARCHAR2', 'NCHAR')
    AND    owner = 'SEARCHSCHEMANAME'
    ORDER BY
           table_name,
           column_name
  )
  LOOP
    l_cmd := 'SELECT COUNT(*)'
         || ' FROM   "' || eachcol.owner || '"."' || eachcol.table_name || '"'
         || ' WHERE  "' || eachcol.column_name || '" LIKE ''%@%.%'''
         || ' AND    ROWNUM = 1';

    EXECUTE IMMEDIATE l_cmd INTO l_found;

    IF l_found > 0 THEN
      DBMS_OUTPUT.PUT_LINE(
        RPAD (eachcol.owner || '.' || eachcol.table_name || '.' || eachcol.column_name, 92)
        || ' may contain email addresses'
      );
    END IF;
  END LOOP;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(l_cmd);
    DBMS_OUTPUT.PUT_LINE(SQLERRM);
    RAISE;
END;
/

字符串
fiddle

相关问题