2013-10-23 60 views
0

需要幫助... PL/SQL新手。我哪裏錯了?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

你似乎在這裏混合了一些東西。

  • 如果你正在創建一個存儲過程,你不會從關鍵字declare開始,那是關於匿名PL/SQL塊的。
  • 您在ISsys_refcursor之間缺少一個變量名稱;據推測這應該是result
  • SQL%NOTFOUND將在結果集中沒有更多行時爲true;它並不表示根本沒有數據,當然也不表示該表(user_objects,實際上是一個視圖)不存在。
  • 您的循環會一直持續下去,因爲您到達結果集的末尾時沒有檢測到。您會從ELSE部件中獲得所有存在的視圖的合理輸出,但隨後每次後續迭代都會得到SQL%NOTFOUND;沒有exit從循環它只會嘗試再次獲取。

如果你使用SQL * Plus或SQL Developer,您可以使用「顯示錯誤」命令來查看爲什麼代碼存儲的塊不會進行編譯,或者您可以查詢user_errors看法,這將在工作其他客戶也一樣。但在這種情況下,直到你從declare那裏得到PLS-00103: Encountered the symbol "CREATE"...錯誤纔會有很大的成效。 (如果你真的在問題中說明你得到了什麼錯誤,它總是會變成heps)。

我覺得這是你似乎在瞄準什麼等價的:

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

你不如果在選擇中生成整個動態語句,則甚至不必定義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; 
/