你似乎在这里混合了一些东西。
- 如果您正在创建一个存储过程,则不要以
declare
关键字开头,那是针对匿名 PL/SQL 块的。
- 您在
IS
and之间缺少变量名sys_refcursor
;大概应该是这样result
。
SQL%NOTFOUND
当结果集中没有更多行时为真;它并不表示根本没有数据,当然也不会表示表(user_objects
实际上是一个视图)不存在。
- 您的循环现在将永远持续下去,因为您没有检测到何时到达结果集的末尾。对于确实存在的所有视图,您将从该
ELSE
部分获得合理的输出,但随后SQL%NOTFOUND
每次迭代都会获得;如果没有exit
来自循环,它只会尝试再次获取。
如果您使用的是 SQL*Plus 或 SQL Developer,您可以使用“显示错误”命令来查看存储的代码块无法编译的原因,或者您可以查询user_errors
也可以在其他客户端中工作的视图。PLS-00103: Encountered the symbol "CREATE"...
但是在这种情况下,除非您从那里克服错误,否则不会做太多事情declare
。(如果您实际上在问题中说明您遇到了什么错误,它总是很高兴)。
我认为这相当于您的目标:
create or replace procedure grant_view_privs is
result sys_refcursor;
strView user_objects.object_name%TYPE;
strQuery varchar2(4000);
begin
open result for
select object_name
from user_objects
where object_type='VIEW'
and status !='INVALID';
loop
fetch result into strView;
exit when SQL%NOTFOUND;
strQuery := 'grant SELECT on '||strView||' to BIOTICS_REPORT';
dbms_output.put_line(strQuery);
execute immediate strQuery;
end loop;
close result;
end grant_view_privs;
/
您可以使用不同形式的游标语法来简化这一点:
create or replace procedure grant_view_privs is
strQuery varchar2(4000);
begin
for curViews in (
select object_name
from user_objects
where object_type='VIEW'
and status !='INVALID'
)
loop
strQuery := 'grant SELECT on '||curViews.object_name||' to BIOTICS_REPORT';
dbms_output.put_line(strQuery);
execute immediate strQuery;
end loop;
end grant_view_privs;
/
strQuery
如果您在选择中生成整个动态语句,您甚至不必定义:
create or replace procedure grant_view_privs is
begin
for curViews in (
select 'grant SELECT on '||object_name||' to BIOTICS_REPORT' as command
from user_objects
where object_type='VIEW'
and status !='INVALID'
)
loop
dbms_output.put_line(curViews.command);
execute immediate curViews.command;
end loop;
end grant_view_privs;
/