Schema wide text search: Difference between revisions

From WickyWiki
Created page with "Search full schema for text. The function 'search' is a simple (but slow) way to find a certain tekst or numer in your Oracle database schema. The result will be in the table 'T..."
 
m 1 revision
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
Search full schema for text.
Search full schema for text.


The function 'search' is a simple (but slow) way to find a certain tekst or numer in your Oracle database schema. The result will be in the table 'T_SEARCHRESULT'. Any exceptions will be reported in the 'founderror' column. For example when datatypes are not supported.
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 t_searchresult;
-- create
create table t_searchresult(
drop table tmp_searchresult;
table_name varchar2(50)
create table tmp_searchresult(
, found NUMBER
    speed timestamp default systimestamp
, minrowid rowid
  , table_name varchar2(32)
, founderror clob);
  , found_count NUMBER
  , table_count number
  , first_rowid rowid
  , found_error clob)
  ;


create or replace procedure search(search_txt VARCHAR2) IS
-- 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(5000);
     where_txt CLOB;
     v_table_name VARCHAR2(30);
    v_sql VARCHAR2(10000);
     v_column_name VARCHAR2(100);
     v_table_name VARCHAR2(40);
     v_column_type VARCHAR2(30);
     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;
BEGIN
     v_id NUMBER;
     delete t_searchresult;
     v_tables_count number := 0;
     insert into t_searchresult(table_name,found) values ('search '''||search_txt||'''',0);
BEGIN
     -- all tables:
     delete tmp_searchresult;
OPEN cursor2 FOR 'select tname from tab
    OPEN cursor2 FOR 'select table_name
      where tname<>''T_SEARCHRESULT'' and not tname like ''%$%'' and tabtype=''TABLE''
        from user_tables
      order by tname';
        where not table_name like ''TMP%''
LOOP
          and not table_name like ''%$%''
FETCH cursor2 INTO v_table_name;
        order by table_name';
EXIT WHEN cursor2%NOTFOUND;
    LOOP
      FETCH cursor2 INTO v_table_name;
      EXIT WHEN cursor2%NOTFOUND;
      v_tables_count := v_tables_count + 1;
       where_txt := NULL;
       where_txt := NULL;
       -- all columns:
       BEGIN
       OPEN cursor1 FOR 'select cname, coltype from col c
        search_num:=TO_NUMBER(search_txt);
          where tname='''||v_table_name||''' and not coltype in (''BLOB'',''"MDSYS"."SDO_GEOMETRY"'') order by colno';
      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;
          FETCH cursor1 INTO v_column_name, v_column_type;
        EXIT WHEN cursor1%NOTFOUND;
          EXIT WHEN cursor1%NOTFOUND;
-- exceptions for certain datatypes
          IF NOT search_num is NULL THEN
        if v_column_type='NUMBER' then
            if v_column_type='NUMBER' then
          v_column_name:='to_char('||v_column_name||')='''||search_txt||'''';
              v_column_where:='"'||v_column_name||'"'||'='||search_txt;
        elsif v_column_type='DATE' then
            else
          v_column_name:='to_char('||v_column_name||',''DD-MM-YYYY'')='''||search_txt||'''';
              v_column_where:=NULL;
        else  
            end if;
           v_column_name:=v_column_name||' like ''%' || search_txt || '%''';
          ELSIF NOT search_dat is NULL THEN
        end if;
            if v_column_type='DATE' then
       
              v_column_where:='upper(to_char('||'"'||v_column_name||'"'||',''DD-MM-YYYY''))=upper('''||search_txt||''')';
        IF where_txt is NULL THEN
            else
          where_txt := v_column_name;
              v_column_where:=NULL;
        ELSE
            end if;
          where_txt := where_txt || ' or ' || v_column_name;
           ELSIF NOT search_txt is NULL THEN
        END IF;
            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
        BEGIN
        execute immediate 'select count(*), min(rowid) from '||v_table_name||' where '||where_txt into v_found, v_rowid;
            v_sql:='insert into tmp_searchresult(table_name, found_count, first_rowid)
        if v_found>0 THEN
                    select :v_table_name, count(*), max(rowid)
          insert into t_searchresult(table_name, found, minrowid) values (v_table_name, v_found, v_rowid);
                      from "'||v_table_name||'"
        END IF;  
                      where '||where_txt
      EXCEPTION WHEN OTHERS THEN  
                      ;
        v_message := 'where=' || where_txt || ', backtrace=' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE || ', sqlerrm=' || SQLERRM;
            execute immediate v_sql using v_table_name;
        insert into t_searchresult(table_name,founderror) values (v_table_name, v_message);
            commit;
       END;
        EXCEPTION WHEN OTHERS THEN
  END LOOP;
            v_message := 'sql=' || v_sql || ', backtrace=' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE || ', sqlerrm=' || SQLERRM;
  CLOSE cursor2;
            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;
/
/


call search('Z08.002982');
-- result
select * from t_searchresult order by found;
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
  ;