以下脚本可让您在数据库中查找自定义值。
我可以找出这个特殊值在哪张桌子上。 但是我不知道表格在哪一列中。 如何找到找到的表的列名。
declare
v_match_count integer;
v_counter integer;
v_owner varchar2(255) := 'HASTANE';
v_data_type varchar2(255) := 'NUMBER';
v_search_string varchar2(4000) := 1455671;
v_sql clob := '';
begin
for cur_tables in (select owner, table_name from all_tables where owner = v_owner and table_name in
(select table_name from all_tab_columns where owner = all_tables.owner and data_type like '%' || upper(v_data_type) || '%')
order by table_name) loop
v_counter := 0;
v_sql := '';
for cur_columns in (select column_name from all_tab_columns where
owner = v_owner and table_name = cur_tables.table_name and data_type like '%' || upper(v_data_type) || '%') loop
if v_counter > 0 then
v_sql := v_sql || ' or ';
end if;
v_sql := v_sql || 'upper(' || cur_columns.column_name || ') like ''%' || upper(v_search_string) || '%''';
v_counter := v_counter + 1;
end loop;
v_sql := 'select count(*) from ' || cur_tables.table_name || ' where ' || v_sql;
execute immediate v_sql
into v_match_count;
if v_match_count > 0 then
dbms_output.put_line('Match in ' || cur_tables.owner || ': ' || cur_tables.table_name || ' - ' || v_match_count || ' records');
end if;
end loop;
exception
when others then
dbms_output.put_line('Error when executing the following: ' || dbms_lob.substr(v_sql, 32600));
end;
/
答案 0 :(得分:0)
这似乎不像您在生产环境中运行的那种代码,因此我认为性能不是您的主要考虑因素。既然如此,为什么不对每个列名执行单独的查询,而不将它们全部加载到具有大量OR的单个查询中呢?也许像您在下面看到的那样。我将您的匿名块移动到存储过程中,以使其更易于重用。
CREATE OR REPLACE PROCEDURE find_cols_with_values (owner_in IN VARCHAR2,
datatype_in IN VARCHAR2,
value_in IN VARCHAR2)
IS
v_match_count INTEGER;
v_sql CLOB := '';
BEGIN
FOR cur_tables
IN ( SELECT owner, table_name
FROM all_tables
WHERE owner = owner_in
AND table_name IN (SELECT table_name
FROM all_tab_columns
WHERE owner = all_tables.owner
AND data_type LIKE
'%'
|| UPPER (datatype_in)
|| '%')
ORDER BY table_name)
LOOP
FOR cur_columns
IN (SELECT column_name
FROM all_tab_columns
WHERE owner = owner_in
AND table_name = cur_tables.table_name
AND data_type LIKE '%' || UPPER (datatype_in) || '%')
LOOP
v_sql :=
'select count(*) from '
|| cur_tables.table_name
|| ' where upper('
|| cur_columns.column_name
|| ') like ''%'
|| UPPER (value_in)
|| '%''';
EXECUTE IMMEDIATE v_sql INTO v_match_count;
IF v_match_count > 0
THEN
DBMS_OUTPUT.put_line (
'Match in '
|| cur_tables.owner
|| ': '
|| cur_tables.table_name
|| '.'
|| cur_columns.column_name
|| ' - '
|| v_match_count
|| ' records');
END IF;
END LOOP;
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
'Error when executing the following: '
|| DBMS_LOB.SUBSTR (v_sql, 32600));
END;
/
CREATE TABLE t1 (mynum NUMBER)
/
CREATE TABLE t2 (yournum VARCHAR2 (100))
/
BEGIN
INSERT INTO t1
VALUES (123);
INSERT INTO t1
VALUES (456);
INSERT INTO t2
VALUES ('123');
COMMIT;
END;
/
BEGIN
find_cols_with_values (owner_in => USER,
datatype_in => 'NUM',
value_in => '123');
END;
/