PL / SQL代码授予新用户在其他用户拥有的视图上选择privs

时间:2013-10-23 16:43:38

标签: oracle view plsql grant

需要帮助... 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;
/

1 个答案:

答案 0 :(得分:1)

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

  • 如果您正在创建存储过程,则不要使用declare关键字启动它,而是使用匿名PL / SQL块。
  • 您在ISsys_refcursor之间缺少变量名称;大概应该是result
  • 当结果集中没有更多行时,
  • SQL%NOTFOUND将为true;它并不表示根本没有数据,当然也不会表明表(user_objects,实际上是一个视图)不存在。
  • 您的循环将在此刻永远继续,因为您没有检测到何时到达结果集的末尾。对于所有存在的视图,您将从ELSE部分获得合理的输出,但随后每次迭代都会获得SQL%NOTFOUND;如果没有来自循环的exit,它只会尝试再次获取。

如果您正在使用SQL * Plus或SQL Developer,您可以使用'show errors'命令来查看存储的代码块无法编译的原因,或者您可以查询可以工作的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;
/

您可以使用cursor语法的不同形式简化这一点:

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;
/

如果在select中生成整个动态语句,则甚至不必定义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;
/