I have found a resolution for the issue I initially raised.
Cause of error: Not specifying a schema; only grabbing user-specific tables.
While the stored procedure would execute when deployed as user ABC, the error generated when running the stored procedure as a user other ABC. It appeared the same table name existed in multiple schemas. Thus, adding an OWNER variable specified the schema associated with the table name and eliminated the error.
Additionally, the procedure was originally searching for USER_TABLES. This limited the results to only the tables of the current schema. By replacing USER_TABLES with DBA_TABLES, the stored procedure's search spanned through all tables of the database.
See below for the corrected code:
CREATE OR REPLACE
PROCEDURE FIND_STRING(
p_str IN VARCHAR2) authid current_user
IS
l_query CLOB;
srchstr VARCHAR2(100) := '';
r_cname VARCHAR2(100) := '';
l_case CLOB;
l_runquery BOOLEAN;
l_tname VARCHAR2(100);
l_cname VARCHAR2(100);
BEGIN
dbms_application_info.set_client_info( '%' || upper(p_str) || '%' );
FOR x IN
(SELECT *
FROM dba_tables
WHERE table_name <> 'CONTROLVALUES'
AND table_name <> 'VALUESEARCHRESULTS'
AND tablespace_name <> 'SYSTEM'
AND tablespace_name <> 'SYSAUX'
AND tablespace_name <> 'TEMP'
AND tablespace_name <> 'UNDOTBS1'
)
LOOP
l_query := 'select ''' || x.owner || '.' || x.table_name || ''', $$
from ' || x.owner || '.' || x.table_name || '
where rownum = 1 and ( 1=0 ';
l_case := 'case ';
l_runquery := FALSE;
FOR y IN
(SELECT *
FROM dba_tab_columns
WHERE table_name = x.table_name
AND owner = x.owner
AND (data_type IN ( 'CHAR', 'DATE', 'FLOAT', 'NCHAR', 'NUMBER', 'NVARCHAR2', 'VARCHAR2' )
OR data_type LIKE 'INTERVAL%'
OR data_type LIKE 'TIMESTAMP%' )
)
LOOP
l_runquery := TRUE;
l_query := l_query || ' or upper(' || y.column_name || ') like userenv (''client_info'') ';
l_case := l_case || ' when upper(' || y.column_name || ') like userenv (''client_info'') then ''' || y.column_name || '''';
END LOOP;
IF ( l_runquery ) THEN
l_case := l_case || ' else NULL end';
l_query := REPLACE( l_query, '$$', l_case ) || ')';
BEGIN
EXECUTE immediate l_query INTO l_tname, l_cname;
r_cname := l_cname;
dbms_application_info.read_client_info(srchstr);
INSERT
INTO VALUESEARCHRESULTS
(
resulttable,
resultcolumn,
searchstring
)
VALUES
(
x.table_name,
r_cname,
srchstr
);
dbms_output.put_line ( srchstr || ' found in ' || l_tname || '.' || l_cname );
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line ( srchstr || ' has no hits in ' || x.owner || '.' || x.table_name );
END;
END IF;
END LOOP;
END;