0

需要帮助... PL/SQL 新手。我哪里错了?

 DECLARE

 CREATE or REPLACE PROCEDURE grant_view_privs

      IS sys_refcursor;
       strVIEWS Varchar2(1000);
       strQuery varchar2(4000);
  BEGIN

  open result for

    select object_name from user_objects where object_type='VIEW'
      and status !='INVALID';
   loop
     fetch result into strVIEWS;

  IF SQL%NOTFOUND then
    DBMS_OUTPUT.PUT_LINE ('TABLE DOES NOT EXIST');

    ELSIF SQL%FOUND then

    DBMS_OUTPUT.PUT('Granting select on '||strVIEWS||' to BIOTICS_REPORT');

    strQuery := 'grant SELECT on '||strVIEWS||' to BIOTICS_REPORT';

    execute immediate strQuery;

    DBMS_OUTPUT.PUT_LINE('SUCCES');
    END IF;
end loop;

close result;

end;
/
4

1 回答 1

1

你似乎在这里混合了一些东西。

  • 如果您正在创建一个存储过程,则不要以declare关键字开头,那是针对匿名 PL/SQL 块的。
  • 您在ISand之间缺少变量名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;
/
于 2013-10-23T17:06:53.200 回答