0

I was wondering if anyone had a query that would search all views to find specific text. The database version we are on is Oracle Database 12c. This will only be run in our dev/test database.

I'm newer to the company, new to this database structure, and new to using Oracle. I've only used MSSQL in the past. I couldn't find a data dictionary and felt bad always having to ask what something meant or where it was located.

I was trying to investigate some before asking. I'm trying to learn what all the columns mean and where all the data is connected to. I'm open to other suggestions.

For SQL, I have one that searches through the views and columns for data and is rather fast. I don't have an exact time. But, I thought it would be similar to running it in Oracle unless the database is a little different to where maybe running something like that won't return as quick. I found some queries for Oracle that search all tables, but I don't have access to any of the tables. How we have been given access is going through: other users > users > views > then query on that view.

I found this link that I thought might work - Oracle Search all tables all columns for string

When I run the first query in the accepted answer I get this error:

Error report -ORA-00932: inconsistent datatypes: expected - got CHAR
ORA-06512: at line 6
00932. 00000 - "inconsistent datatypes: expected %s got %s"
*Cause:
*Action:"` 

The string that I am searching for contains numbers and letters. Ex. 123ABC

When I run the second query, I let it run for four hours and still nothing returned. Is there anyway to speed that one up?

I'm open to any other queries, suggestions, and help of pointing me in the right direction.

Thank you!

Littlefoot
  • 131,892
  • 15
  • 35
  • 57
Austin
  • 31
  • 5

1 Answers1

0

You have to understand that searching all CHAR (and its variations) datatype columns (as "123ABC" is a string) within the whole database is a tedious and a long time running process. It takes no time in a few relatively small tables; but, on a large database, it really takes a long time. You can't use any indexes, so ... be patient.

Also, note that code (behind that link) searches through ALL_TAB_COLUMNS view which contains not only your tables' columns (owned by you), but everything you have access to, and that contains various users. Have a look; that's my 11gXE database on a laptop:

SQL> select owner, count(*) from all_tab_columns group by owner;

OWNER                            COUNT(*)
------------------------------ ----------
MDSYS                                 736
CTXSYS                                320
SYSTEM                                 54
APEX_040000                          3327
SCOTT                                  69
XDB                                    35
SYS                                 15211

7 rows selected.

SQL> select count(*) from user_tab_columns;

  COUNT(*)
----------
        69

SQL>

See the difference? Using ALL_TAB_COLUMNS, you're searching through ~20.000 columns. In my own schema (and USER_TAB_COLUMNS), that's only 70 of them.

Therefore, consider switching to USER_TAB_COLUMNS (if you do, remove all OWNER column references).


PL/SQL procedure (in this case (regarding code you took from the question whose link you posted), an anonymous PL/SQL block) won't display anything until it is over.

Alternatively, you could create a "log" table, an autonomous transaction stored procedure (so that you could insert into the log table and commit) so that you'd then "trace" execution from another session. Something like this:

Log table and procedure:

SQL> create table search_log (table_name varchar2(30), column_name varchar2(30));

Table created.

SQL> create or replace procedure p_log (par_table_name in varchar2,
  2                                     par_column_name in varchar2)
  3  is
  4    pragma autonomous_transaction;
  5  begin
  6    insert into search_log (table_name, column_name)
  7      values (par_table_name, par_column_name);
  8    commit;
  9  end;
 10  /

Procedure created.

Code from the link you posted; switched to USER_TAB_COLUMNS, searching for table/column that contains the 'KING' string:

SQL> DECLARE
  2    match_count integer;
  3    v_search_string varchar2(4000) := 'KING';
  4  BEGIN
  5    FOR t IN (SELECT table_name, column_name
  6              FROM user_tab_columns
  7              WHERE data_type like '%CHAR%'
  8             )
  9    LOOP
 10      EXECUTE IMMEDIATE
 11        'SELECT COUNT(*) FROM '|| t.table_name||
 12        ' WHERE '||t.column_name||' = :1'
 13         INTO match_count
 14        USING v_search_string;
 15      IF match_count > 0 THEN
 16        --dbms_output.put_line( t.owner || '.' || t.table_name ||' '||t.column_name||' '||match_count );
 17        p_log(t.table_name, t.column_name);
 18      END IF;
 19    END LOOP;
 20  END;
 21  /

PL/SQL procedure successfully completed.

SQL> select * From search_log;

TABLE_NAME                     COLUMN_NAME
------------------------------ ------------------------------
EMP                            ENAME

SQL>

Only one table found; EMP and its ENAME column.

Littlefoot
  • 131,892
  • 15
  • 35
  • 57
  • Thanks for explaining everything for me. When I run the count for user_tab_columns, I get 45 back. I was wondering why nothing was returning when running the PL/SQL block. So if I create the procedure, it will show in real time, or I would still have to wait til it's finished? Seems like it would show in real time by reading your comment. I tried to create the table, but I don't have permissions to create a table. I can only run queries against a user's views. What would be my next option? Will Oracle time out after so long if I let a long query run? – Austin Jan 05 '22 at 17:22
  • You'll have to wait until it finishes, but - connected to another session, you'd be able to query the log table and check whether code you wrote found anything (or nothing). If you include a *timestamp* column, you'll know *when* it was found which might be useful if you opt to use ALL_... view (which lasts for hours). If you can't create a table in that schema, is there any other you can use? Then create the table there, grant privileges to your current user. Or talk to DBA, they might want to create log facility for you. – Littlefoot Jan 05 '22 at 19:09