[英]Oracle: Search an entire DB for a string: Error ORA-00911
我已经在下面创建了PL / SQL存储过程,以在整个Oracle11g数据库中搜索字符串(srchstr),并将找到该字符串的表和列返回到名为VALUESEARCHRESULTS的表中。
该过程已作为用户通过SQL Developer在Oracle XE中成功运行。 但是,当尝试在Oracle11g中以用户SYS的身份针对架构ABC运行它时,出现以下错误:
ORA-00911:无效字符原因:标识符不能以字母和数字以外的任何ASCII字符开头。 $#_也允许在第一个字符之后。 用双引号引起来的标识符可以包含除双引号以外的任何字符。 替代引号(q“#...#”)不能使用空格,制表符或回车符作为分隔符。 对于所有其他上下文,请查阅《 SQL语言参考手册》。
有谁知道为什么会这样吗? 请在下面查看我的代码。
CREATE OR REPLACE PROCEDURE ABC.FIND_STRING(p_str IN VARCHAR2) authid current_user is
l_query clob;
srchstr varchar2(30) := '';
r_cname varchar2(30) := '';
l_case clob;
l_runquery boolean;
l_tname varchar2(30);
l_cname varchar2(30);
begin
dbms_application_info.set_client_info( '%' || upper(p_str) || '%' );
for x in (select * from user_tables)
loop
l_query := 'select ''' || x.table_name || ''', $$
from ' || x.table_name || '
where rownum = 1 and ( 1=0 ';
l_case := 'case ';
l_runquery := FALSE;
for y in ( select *
from user_tab_columns
where table_name = x.table_name
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 ABC.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.table_name );
end;
end if;
end loop;
end;
编辑 :上面的存储的过程编译没有错误。 下面的代码通过将表中的值传递到存储过程中来执行存储过程。 该错误显示何时运行以下代码:
BEGIN
FOR c IN (SELECT ControlValue FROM ABC.ControlValues) LOOP
ABC.FIND_STRING(c.ControlValue);
END LOOP;
END;
我已经找到了最初提出的问题的解决方案。
错误原因:未指定架构; 仅抓取用户特定的表。
当存储过程将以用户ABC身份部署时将执行,而以用户ABC身份运行存储过程时将生成错误。 似乎在多个模式中存在相同的表名。 因此,添加OWNER变量可指定与表名关联的架构,并消除了错误。
此外,该过程最初是在搜索USER_TABLES。 这将结果限制为仅当前模式的表。 通过用DBA_TABLES替换USER_TABLES,存储过程的搜索遍及了数据库的所有表。
请参阅下面的更正代码:
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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.