I'm trying to write a PL/SQL script that searches the entire database for a string and report the tables and columns it finds it in. It looks like this:
DECLARE
ncount NUMBER;
vwhere VARCHAR2(1000) := '';
vsearchstr VARCHAR2(1000) := 'search string here';
vresult VARCHAR2(10000) := 'result: ';
vtab VARCHAR2(1000) := '';
vcol VARCHAR2(1000) := '';
BEGIN
FOR k IN (SELECT a.table_name, a.column_name FROM all_tab_columns a WHERE a.data_type LIKE '%VARCHAR%')
LOOP
vtab := k.table_name;
vcol := k.column_name;
vwhere := ' where ' || vcolumnname || ' = :vsearchstr ';
EXECUTE IMMEDIATE 'select count(1) from ' || vtab || vwhere INTO ncount USING vsearctstr;
IF (ncount > 0)
THEN
vresult := CONCAT(vresult, vcol || ' ' || vtab || ', ');
END IF;
END LOOP;
IF (LENGTH(vresult) > 1)
THEN
dbms_output.put_line(vresult);
ELSE
dbms_output.put_line('not found');
END IF;
END;
When I run it, I get the following error:
It is essentially saying it doesn't recognize the table vtab in the line EXECUTE IMMEDIATE 'select count(1) from ' || vtab || vwhere INTO ncount USING vsearctstr.
So in order to see which table it's complaining about, I added the following exception block to the end of the script:
EXCEPTION
WHEN OTHERS
THEN
BEGIN
dbms_output.put_line('exception: ' || vtab);
END;
It tells me the table name is IND$.
I'm not sure what this table (or view) is and it doesn't look relevant anyway.
So my question is two fold: 1) If it is fetching IND$ in the FOR loop from k.table_name (which in turn is from all_tab_columns), why does it say it doesn't exist in the select query? 2) I'm not sure what IND$ is but I'm pretty sure I don't need to search it; So is there a way to limit my search to only relevant tables (not views)? By 'relevant', I mean tables that we created to store data for our application (as opposed to system tables or user tables, etc.).
Thanks very much.

all_tab_columnslists columns in all tables that your current schema has access to. In general, if you're going to use ALL_... views to build dynamic SQL, you should incorporate theOWNERcolumn as well since it may return rows for tables in other schemas.If you really only want to consider tables in your current schema, use
user_tab_columnsinstead.If you want to get more, or less, particular than that about which tables are 'relevant', then you'll probably need to hardcode specific rules into your query.
FYI:
IND$is part of the Oracle data dictionary and is in the SYS schema. (Although, it's always possible someone has created a table with that name in some other schema.) It's unusual that your application schema would have direct access to this.