2014-04-18 25 views
0

我遇到問題。 SET ROLE不能按我的預期工作。我有代碼示例:SET ROLES無法正常工作

DECLARE 
    ln_ln NUMBER; 
    ln_1 NUMBER; 
BEGIN 
    ln_ln := DBMS_SQL.OPEN_CURSOR; 
    DBMS_SQL.PARSE(ln_ln, 'SET ROLE SOME_ROLE IDENTIFIED BY SOME_PASSWORD',DBMS_SQL.NATIVE); 
    ln_1 := DBMS_SQL.EXECUTE(ln_ln); 
    DBMS_SQL.CLOSE_CURSOR(ln_ln); 
    ln_ln := SOME_PACKAGE.SOME_FUNCTION; 
END; 

SOME_ROLE有贈款SOME_PACKAGE。當我運行這個塊時,我收到包不存在的錯誤。當我運行這一切都很好:

DECLARE 
    ln_ln NUMBER; 
    ln_1 NUMBER; 
BEGIN 
    ln_ln := DBMS_SQL.OPEN_CURSOR; 
    DBMS_SQL.PARSE(ln_ln, 'SET ROLE SOME_ROLE IDENTIFIED BY SOME_PASSWORD',DBMS_SQL.NATIVE); 
    ln_1 := DBMS_SQL.EXECUTE(ln_ln); 
    DBMS_SQL.CLOSE_CURSOR(ln_ln); 
END; 
/
DECLARE 
    ln_ln NUMBER; 
BEGIN 
    ln_ln := SOME_PACKAGE.SOME_FUNCTION; 
END; 

當我運行它,一切都很好過:

DECLARE 
    ln_ln NUMBER; 
BEGIN 
    ln_ln := DBMS_SQL.OPEN_CURSOR; 
    DBMS_SQL.PARSE(ln_ln, 'SET ROLE SOME_ROLE IDENTIFIED BY SOME_PASSWORD',DBMS_SQL.NATIVE); 
    ln_1 := DBMS_SQL.EXECUTE(ln_ln); 
    DBMS_SQL.CLOSE_CURSOR(ln_ln); 
    EXECUTE IMMEDIATE 'BEGIN :x := SOME_PACKAGE.SOME_FUNCTION; END;' USING OUT ln_ln; 
END; 

我試過EXECUTE IMMDIATEDBMS_SESSION.SET_ROLEDBMS_UTILITY.exec_ddl_statement,而不是DBMS_SQL.EXECUTE。任何人都可以告訴我一些解決方法或解釋爲什麼這種事情繼續發生。

回答

2

正如我所承諾的,在運行SET ROLE之前,您無權訪問SOME_PACKAGE。 在這種情況下,您的第一個腳本將無法工作,因爲pl/sql不是腳本語言,它在運行之前會編譯代碼。解析器到達SOME_PACKAGE時,它會失敗,因爲用戶不知道該字符串是什麼。

你已經有一個解決方案:

  1. 使2 anonimous塊

    • 授予權限
    • 執行功能(該塊被執行第一個塊後,才編譯)
  2. 使用動態SQL像EXECUTE IMMEDIATE(代碼發佈在運行時)

+0

但有沒有什麼辦法可以在設置角色後重新解析匿名塊?我想讓第一個選項工作,因爲那樣我就不必重做900多個組件:) –

+0

唯一的選擇是在執行前設置角色。如果此塊是您不控制的應用程序的一部分,則可以使用onlogon觸發器來設置適當的權限。另一件事......如果所有900個組件看起來都很相似,那麼你可以寫一個轉換器到「立即執行」解決方案。 – vav

+0

謝謝你的回答,我決定做一個腳本,把一個anonimus塊分成兩塊。 –