Schema wide text search: Difference between revisions
From WickyWiki
m 1 revision |
m 1 revision |
||
| (One intermediate revision by the same user not shown) | |||
| Line 1: | Line 1: | ||
Search full schema for text. | Search full schema for text. | ||
The | The pl/sql block is a simple (but slow) way to find a certain text or number in your Oracle database schema. The result will be in the table 'tmp_searchresult'. Any exceptions will be reported in the 'found_error' column. For example when datatypes are not supported. | ||
<syntaxhighlight lang=sql> | <syntaxhighlight lang=sql> | ||
drop table | -- create | ||
create table | drop table tmp_searchresult; | ||
create table tmp_searchresult( | |||
speed timestamp default systimestamp | |||
, table_name varchar2(32) | |||
, found_count NUMBER | |||
, table_count number | |||
, first_rowid rowid | |||
, found_error clob) | |||
; | |||
-- search | |||
BEGIN | BEGIN | ||
DECLARE | DECLARE | ||
search_txt VARCHAR2(50) := 'Stichting Waternet'; | |||
search_num NUMBER; | |||
search_dat date; | |||
TYPE curTyp IS REF CURSOR; | TYPE curTyp IS REF CURSOR; | ||
cursor1 curTyp; | cursor1 curTyp; | ||
cursor2 curTyp; | cursor2 curTyp; | ||
where_txt VARCHAR2( | where_txt CLOB; | ||
v_table_name VARCHAR2( | v_sql VARCHAR2(10000); | ||
v_column_name VARCHAR2(100); | v_table_name VARCHAR2(40); | ||
v_column_type VARCHAR2( | v_column_name VARCHAR2(40); | ||
v_column_where VARCHAR2(100); | |||
v_column_type VARCHAR2(40); | |||
v_found number; | v_found number; | ||
v_message clob; | v_message clob; | ||
v_rowid rowid; | v_rowid rowid; | ||
v_id NUMBER; | |||
v_tables_count number := 0; | |||
BEGIN | |||
delete tmp_searchresult; | |||
OPEN cursor2 FOR 'select table_name | |||
from user_tables | |||
where not table_name like ''TMP%'' | |||
and not table_name like ''%$%'' | |||
order by table_name'; | |||
LOOP | |||
FETCH cursor2 INTO v_table_name; | |||
EXIT WHEN cursor2%NOTFOUND; | |||
v_tables_count := v_tables_count + 1; | |||
where_txt := NULL; | where_txt := NULL; | ||
-- | BEGIN | ||
OPEN cursor1 FOR 'select | search_num:=TO_NUMBER(search_txt); | ||
EXCEPTION WHEN OTHERS THEN | |||
search_num:=NULL; | |||
END; | |||
BEGIN | |||
search_dat:=TO_DATE(search_txt,'DD-MM-YYYY'); | |||
EXCEPTION WHEN OTHERS THEN | |||
search_dat:=NULL; | |||
END; | |||
OPEN cursor1 FOR 'select column_name, data_type from cols | |||
where not DATA_TYPE in (''BLOB'',''SDO_GEOMETRY'',''LONG'') | |||
and table_name='''||v_table_name||''' order by COLUMN_ID'; | |||
LOOP | LOOP | ||
FETCH cursor1 INTO v_column_name, v_column_type; | |||
EXIT WHEN cursor1%NOTFOUND; | |||
IF NOT search_num is NULL THEN | |||
if v_column_type='NUMBER' then | |||
v_column_where:='"'||v_column_name||'"'||'='||search_txt; | |||
else | |||
v_column_where:=NULL; | |||
end if; | |||
ELSIF NOT search_dat is NULL THEN | |||
if v_column_type='DATE' then | |||
v_column_where:='upper(to_char('||'"'||v_column_name||'"'||',''DD-MM-YYYY''))=upper('''||search_txt||''')'; | |||
else | |||
v_column_where:=NULL; | |||
end if; | |||
ELSIF NOT search_txt is NULL THEN | |||
if v_column_type='NUMBER' or v_column_type='DATE' then | |||
v_column_where:=NULL; | |||
else | |||
v_column_where:='upper("'||v_column_name||'")'||' like ''%' || upper(search_txt) || '%'''; | |||
end if; | |||
END IF; | |||
IF NOT v_column_where is NULL THEN | |||
IF where_txt is NULL THEN | |||
where_txt := v_column_where; | |||
ELSE | |||
where_txt := where_txt || ' OR ' || v_column_where; | |||
END IF; | |||
END IF; | |||
END LOOP; | END LOOP; | ||
CLOSE cursor1; | CLOSE cursor1; | ||
IF NOT where_txt is NULL THEN | |||
BEGIN | |||
v_sql:='insert into tmp_searchresult(table_name, found_count, first_rowid) | |||
select :v_table_name, count(*), max(rowid) | |||
from "'||v_table_name||'" | |||
where '||where_txt | |||
; | |||
execute immediate v_sql using v_table_name; | |||
commit; | |||
END; | EXCEPTION WHEN OTHERS THEN | ||
v_message := 'sql=' || v_sql || ', backtrace=' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE || ', sqlerrm=' || SQLERRM; | |||
insert into tmp_searchresult(speed,table_name,found_error) values (sysdate,v_table_name, v_message); | |||
commit; | |||
END; | |||
END IF; | |||
END LOOP; | |||
CLOSE cursor2; | |||
insert into tmp_searchresult(table_name, found_count, table_count, first_rowid) values ('<searched>', null, v_tables_count, null); | |||
END; | END; | ||
END; | END; | ||
/ | / | ||
-- result | |||
select 'select * from "'||table_name||'" where rowid = '''||FIRST_ROWID||'''; --'||FOUND_COUNT | |||
from tmp_searchresult | |||
where FOUND_COUNT>0 | |||
order by table_name | |||
; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
[[Category:SynUpd]] | |||
[[Category:Oracle]] | [[Category:Oracle]] | ||
[[Category:Oracle PL/SQL]] | [[Category:Oracle PL/SQL]] | ||
[[Category:201111]] | [[Category:201111]] | ||
Latest revision as of 06:23, 6 February 2014
Search full schema for text.
The pl/sql block is a simple (but slow) way to find a certain text or number in your Oracle database schema. The result will be in the table 'tmp_searchresult'. Any exceptions will be reported in the 'found_error' column. For example when datatypes are not supported.
-- create
drop table tmp_searchresult;
create table tmp_searchresult(
speed timestamp default systimestamp
, table_name varchar2(32)
, found_count NUMBER
, table_count number
, first_rowid rowid
, found_error clob)
;
-- search
BEGIN
DECLARE
search_txt VARCHAR2(50) := 'Stichting Waternet';
search_num NUMBER;
search_dat date;
TYPE curTyp IS REF CURSOR;
cursor1 curTyp;
cursor2 curTyp;
where_txt CLOB;
v_sql VARCHAR2(10000);
v_table_name VARCHAR2(40);
v_column_name VARCHAR2(40);
v_column_where VARCHAR2(100);
v_column_type VARCHAR2(40);
v_found number;
v_message clob;
v_rowid rowid;
v_id NUMBER;
v_tables_count number := 0;
BEGIN
delete tmp_searchresult;
OPEN cursor2 FOR 'select table_name
from user_tables
where not table_name like ''TMP%''
and not table_name like ''%$%''
order by table_name';
LOOP
FETCH cursor2 INTO v_table_name;
EXIT WHEN cursor2%NOTFOUND;
v_tables_count := v_tables_count + 1;
where_txt := NULL;
BEGIN
search_num:=TO_NUMBER(search_txt);
EXCEPTION WHEN OTHERS THEN
search_num:=NULL;
END;
BEGIN
search_dat:=TO_DATE(search_txt,'DD-MM-YYYY');
EXCEPTION WHEN OTHERS THEN
search_dat:=NULL;
END;
OPEN cursor1 FOR 'select column_name, data_type from cols
where not DATA_TYPE in (''BLOB'',''SDO_GEOMETRY'',''LONG'')
and table_name='''||v_table_name||''' order by COLUMN_ID';
LOOP
FETCH cursor1 INTO v_column_name, v_column_type;
EXIT WHEN cursor1%NOTFOUND;
IF NOT search_num is NULL THEN
if v_column_type='NUMBER' then
v_column_where:='"'||v_column_name||'"'||'='||search_txt;
else
v_column_where:=NULL;
end if;
ELSIF NOT search_dat is NULL THEN
if v_column_type='DATE' then
v_column_where:='upper(to_char('||'"'||v_column_name||'"'||',''DD-MM-YYYY''))=upper('''||search_txt||''')';
else
v_column_where:=NULL;
end if;
ELSIF NOT search_txt is NULL THEN
if v_column_type='NUMBER' or v_column_type='DATE' then
v_column_where:=NULL;
else
v_column_where:='upper("'||v_column_name||'")'||' like ''%' || upper(search_txt) || '%''';
end if;
END IF;
IF NOT v_column_where is NULL THEN
IF where_txt is NULL THEN
where_txt := v_column_where;
ELSE
where_txt := where_txt || ' OR ' || v_column_where;
END IF;
END IF;
END LOOP;
CLOSE cursor1;
IF NOT where_txt is NULL THEN
BEGIN
v_sql:='insert into tmp_searchresult(table_name, found_count, first_rowid)
select :v_table_name, count(*), max(rowid)
from "'||v_table_name||'"
where '||where_txt
;
execute immediate v_sql using v_table_name;
commit;
EXCEPTION WHEN OTHERS THEN
v_message := 'sql=' || v_sql || ', backtrace=' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE || ', sqlerrm=' || SQLERRM;
insert into tmp_searchresult(speed,table_name,found_error) values (sysdate,v_table_name, v_message);
commit;
END;
END IF;
END LOOP;
CLOSE cursor2;
insert into tmp_searchresult(table_name, found_count, table_count, first_rowid) values ('<searched>', null, v_tables_count, null);
END;
END;
/
-- result
select 'select * from "'||table_name||'" where rowid = '''||FIRST_ROWID||'''; --'||FOUND_COUNT
from tmp_searchresult
where FOUND_COUNT>0
order by table_name
;