搜索每个模式的每个列的正则表达式的每一列

时间:2016-03-09 09:45:26

标签: regex oracle plsql

我正在为一家正在接受收购的公司工作。他们使用Oracle 11g,并要求在其数据库中识别对当前公司名称的所有引用,并按照该列中的架构/所有者,表,列和出现次数列出这些引用。

我使用了以下内容并取得了一些成功,如另一个答案所示。

     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 'NAME';

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

然而,它只找到NAME的文字字符串,我也想找到Name,Name Shops,Name Accounts,Name someOtherStringICantGuess等。所以我想我应该使用正则表达式。我对正则表达式部分很好,但它是如何将它合并到我不确定的上述功能中。事实上,我不确定我是否会调整上面的代码,或做一些完全不同的事情。

最后一件事:脚本运行的性能和持续时间是无关紧要的,并且从属于每个被检查列的确定性。有一个专门的环境模仿生产这个脚本的部署,这样就不会对公司的客户产生负面影响。

提前致谢。

编辑:刚刚删除了一些公司特定的代码......

2 个答案:

答案 0 :(得分:0)

最简单的方法是使用upper围绕您的搜索。

    SET SERVEROUTPUT ON SIZE 100000

DECLARE
   -- set l_wildcard_search to true if you are using wildcards ('%'),
   -- false if you want a straight match on the name
   -- Wild card searches (like) are not able to use indexes whereas '='
   -- potentially can.
   l_wildcard_search   CONSTANT BOOLEAN := FALSE;
   match_count                  INTEGER;
   --
   l_searchvalue                VARCHAR2 (100) := UPPER ('NAME');
   l_cmd                        VARCHAR2 (200);
BEGIN
   FOR t IN (SELECT owner, table_name, column_name
               FROM all_tab_columns
              WHERE owner NOT IN ('SYS', 'SYSTEM')
                AND data_type LIKE '%CHAR%')
   LOOP
      BEGIN
         l_cmd      :=    'SELECT COUNT(*) FROM '
                       || t.owner
                       || '.'
                       || t.table_name
                       || ' WHERE upper('
                       || t.column_name
                       || ')'
                       || CASE WHEN l_wildcard_search THEN ' like ' ELSE ' = ' END
                       || ':1';
         DBMS_OUTPUT.put_line (l_cmd);

         EXECUTE IMMEDIATE l_cmd INTO match_count USING l_searchvalue;

         IF match_count > 0
         THEN
            DBMS_OUTPUT.put_line (t.owner || ' ' || t.table_name || ' ' || t.column_name || ' ' || match_count);
         END IF;
      EXCEPTION
         WHEN OTHERS
         THEN
            DBMS_OUTPUT.put_line ('Error executing: ' || l_cmd);
      END;
   END LOOP;
END;
/

答案 1 :(得分:0)

以下是使用正则表达式的答案

SET SERVEROUTPUT ON SIZE 100000

DECLARE

   match_count                  INTEGER;
   l_searchvalue                VARCHAR2 (100) := UPPER ('NAME');
   l_cmd                        VARCHAR2 (200);
BEGIN
   FOR t IN (SELECT owner, table_name, column_name
               FROM all_tab_columns
              WHERE owner NOT IN ('SYS', 'SYSTEM')
                AND data_type LIKE '%CHAR%' and rownum < 10)
   LOOP
      BEGIN
         l_cmd      :=    'SELECT COUNT(*) FROM '
                       || t.owner
                       || '.'
                       || t.table_name
                       || ' WHERE regexp_like('
                       || t.column_name
                       || ', :1)';
         DBMS_OUTPUT.put_line (l_cmd);

         EXECUTE IMMEDIATE l_cmd INTO match_count USING l_searchvalue;

         IF match_count > 0
         THEN
            DBMS_OUTPUT.put_line (t.owner || ' ' || t.table_name || ' ' || t.column_name || ' ' || match_count);
         END IF;
      EXCEPTION
         WHEN OTHERS
         THEN
            DBMS_OUTPUT.put_line ('Error executing: ' || l_cmd);
      END;
   END LOOP;
END;
/