我正在为一家正在接受收购的公司工作。他们使用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等。所以我想我应该使用正则表达式。我对正则表达式部分很好,但它是如何将它合并到我不确定的上述功能中。事实上,我不确定我是否会调整上面的代码,或做一些完全不同的事情。
最后一件事:脚本运行的性能和持续时间是无关紧要的,并且从属于每个被检查列的确定性。有一个专门的环境模仿生产这个脚本的部署,这样就不会对公司的客户产生负面影响。
提前致谢。
编辑:刚刚删除了一些公司特定的代码......
答案 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;
/