Поиск значения по всем таблицам
Вариант1:
DECLARE match_count INTEGER; query_str VARCHAR2(400); l_owner VARCHAR2(10) := 'SCOTT'; l_search_text VARCHAR2(100) := '10'; BEGIN FOR t IN (select table_name, column_name FROM all_tab_columns a where owner = l_owner and a.data_type in ('NUMBER', 'VARCHAR2') ) LOOP begin match_count := 0; query_str := 'SELECT COUNT(*) FROM ' ||l_owner||'.'|| t.table_name || ' WHERE to_char(' || t.column_name || ') = :1'; EXECUTE IMMEDIATE query_str INTO match_count USING l_search_text; IF match_count > 0 THEN dbms_output.put_line(l_owner||'.'||t.table_name || ' ' || t.column_name || ' ' || match_count); dbms_output.put_line(' SELECT t.'|| t.column_name || ', t.* from '||l_owner||'.'|| t.table_name||' t where to_char(' || t.column_name || ') = '''||l_search_text||''''); dbms_output.put_line(''); END IF; exception when others then dbms_output.put_line(t.table_name||'.'||t.column_name||' : '||SQLERRM||' : '||SQLCODE); dbms_output.put_line(query_str); dbms_output.put_line(''); /*raise*/ end; END LOOP; END;
Вариант2:
--SET SERVEROUTPUT ON SIZE 1000000 DECLARE TYPE tab_columns_rec_type IS RECORD ( table_name all_tab_columns.table_name%type ,column_name all_tab_columns.column_name%type ,data_type all_tab_columns.data_type%type ); type tab_columns_tab_type is table of tab_columns_rec_type index by binary_integer; l_tab_columns_rec tab_columns_tab_type; match_count INTEGER; query_str VARCHAR2(400); l_owner VARCHAR2(10) := 'SCOTT'; l_search_text VARCHAR2(100) := '10'; -- % добавляем здесь, если ищем не по точному вхождению l_number NUMBER; is_number NUMBER(1); l_str_length NUMBER; /* l_mode: 1 - NUMBER и VARCHAR2 2 - only NUMBER 3 - only VARCHAR2 */ l_mode NUMBER := 1; -- При каком количестве найденные совпадений -- прекращать поиск l_found_count NUMBER := 1; l_exists_count NUMBER; BEGIN l_str_length := length(l_search_text); begin l_number := to_number(l_search_text); is_number := 1; exception when VALUE_ERROR then is_number := 0; end; if (l_mode = 1 and is_number = 1) then select table_name, column_name, data_type bulk collect into l_tab_columns_rec FROM all_tab_columns a where owner = l_owner and a.data_length >= l_str_length and ( a.data_type = 'VARCHAR2' or a.data_type = 'NUMBER' ); elsif (l_mode = 2 and is_number = 1) then select table_name, column_name, data_type bulk collect into l_tab_columns_rec FROM all_tab_columns a where owner = l_owner and a.data_length >= l_str_length and a.data_type = 'NUMBER'; else select table_name, column_name, data_type bulk collect into l_tab_columns_rec FROM all_tab_columns a where owner = l_owner and a.data_length >= l_str_length and a.data_type = 'VARCHAR2'; end if; l_exists_count := 0; if NOT (l_tab_columns_rec is null or l_tab_columns_rec.count = 0) then for j in l_tab_columns_rec.first..l_tab_columns_rec.last LOOP begin match_count := 0; if (l_tab_columns_rec(j).data_type = 'VARCHAR2') then query_str := 'SELECT count(*) FROM ' ||l_owner||'.'|| l_tab_columns_rec(j).table_name || ' WHERE rownum = 1 and to_char(' || l_tab_columns_rec(j).column_name || ') = :1'; EXECUTE IMMEDIATE query_str INTO match_count USING l_search_text; elsif (l_tab_columns_rec(j).data_type = 'NUMBER') then query_str := 'SELECT count(*) FROM ' ||l_owner||'.'|| l_tab_columns_rec(j).table_name || ' WHERE rownum = 1 and ' || l_tab_columns_rec(j).column_name || ' = :1'; EXECUTE IMMEDIATE query_str INTO match_count USING l_number; end if; IF match_count > 0 THEN l_exists_count := l_exists_count + 1; dbms_output.put_line(l_tab_columns_rec(j).data_type||' '||l_owner||'.'||l_tab_columns_rec(j).table_name || ' ' || l_tab_columns_rec(j).column_name ); dbms_output.put_line(' SELECT t.'|| l_tab_columns_rec(j).column_name || ', t.* from '||l_owner||'.'|| l_tab_columns_rec(j).table_name||' t where to_char(' || l_tab_columns_rec(j).column_name || ') like '''||l_search_text||''''); dbms_output.put_line(''); if (l_exists_count = l_found_count) then exit; end if; END IF; exception when others then dbms_output.put_line(l_tab_columns_rec(j).table_name||'.'||l_tab_columns_rec(j).column_name||' : '||SQLERRM||' : '||SQLCODE); dbms_output.put_line(query_str); dbms_output.put_line(''); /*raise*/ end; END LOOP; end if; END;
Можно сделать небольшую оптимизацию скрипту по количеству элементов в цикле:
ошибся в коде
вместо «is_number := 0;» нужно конечно использовать «is_number := 1;» и наоборот.
@maart
мне проще закоментировать ненужный тип в строке
Но конечно, кому как удобно.
Я написал процедуру в своем пакете с утилитами, и в зависимости от входных параметров применяется разная логика поиска. Из неё и кусочек кода приложил.
Например, добавил ещё два параметра. Первый отвечает за операнд «=» или «like ‘%i_str%'». Второй отвечает за регистр букв — учитывать или не учитывать.
Maart, приветствую! Очень нужен такой полезный скриптец — поиск заданного значения во всех таблицах и поиск объектов, которые сожержат, например заданное название столбца. Можешь, плиз, поделиться скриптами, от начала и до конца. Указанные здесь не срабатывают — 1 -й зависает напрочь, а твою оптимизацию не совсем понимаю…
Заранее спасибо!
P.S. Для Oracle …
Добавил второй вариант, работает быстрее.
Привет! Спасибо большое за оперативность — даже не ожидала такого скорого ответа! Единственное но… почему-то у меня оба этих скрипта виснут — я уж минут через 15 прерываю выполнение — надоедает ждать…
Ты можешь, их, плиз, как-то оптимизировать?
Буду тебе крайне признательна и благодарна!!! ;)
@sunsbaby
По большой схеме будет работать долго. У меня, например, отрабатывает около 1 часа.
Для оптимизации можно ограничить названия таблиц, если примерно известно в каких лежат данные.
Чуток подправил вариант2, добавил параметр
@rudev
Спасибо огромнейшее! Ещё маленький глупый вопросик… У меня отработал 2-й вриант, но в рез-те тока написал «anonymous block completed» …а где же сам ответ посмотреть можно? :))
P.S. готова тебя расцеловать (если тебя это интересует…….) ;) :))
@sunsbaby
В PL/SQL Developer можно просмотреть так:
Если в SQL-PLUS, то раскомментировать первую строку:
@rudev
A если Oracle SQL?
P.S. Может это как-то преобразовать в процедуру или функцию? :)
@sunsbaby
Для SQL Developer
Ура! Получилось! ТЫ супер-пупер программер!!!! :)
Здравствуйте, уважаемый
Очень нужен этот полезный скриптец – поиск заданного значения во всех таблицах и поиск объектов, которые содержат, например заданное название столбца.
Может, поделитесь скриптами, от начала и до конца.
Заранее благодарю,
Вадим
Все, что вам надо, уже есть в посте.
поиск заданного значения во всех таблицах — это вариант1 и вариант2
поиск объектов, которые содержат, например заданное название столбца — таблица all_tab_columns
Респект за скрипт, работает, пригодился! Переслал коллегам.