2017-03-01 59 views
0

我想直接授予,因爲從PLSQL授予是不允許的。這裏是我的存儲過程:如何從存儲過程啓動SQL命令行?

connect pta/[email protected] 

create or replace procedure refresh_all_privs_in_role(p_role_code varchar2)  
is  
    v_role role.role_db%type;     
    type rec_user is table of varchar2(30) index by binary_integer;  
    v_users rec_user;  
    counter integer := 0;    
    type rec_menu_priv is table of menu.menu_role_priv%type index by binary_integer;  
    v_privs rec_menu_priv;     

    function get_menu_privs(p_menu_id number)  
    return rec_menu_priv 
    is  
     privs menu.menu_role_priv%type;  
     ret rec_menu_priv;  
     counter_priv integer := 0;  
    begin  
     select menu_role_priv into privs from menu where menu_id = p_menu_id;  
     if instr(privs,'|') = 0 then  
      ret(1) := privs;  
     else  
      while instr(privs,'|') > 0 loop  
       counter_priv := counter_priv + 1;  
       ret(counter_priv) := substr(privs, 1, instr(privs,'|') - 1);  
       privs := substr(privs, instr(privs,'|') + 1);  
      end loop;  
      counter_priv := counter_priv + 1;  
      ret(counter_priv) := privs;  
     end if;  
     return ret;  
    end;    
begin  
    select lower(role_db) into v_role from role where role_code = p_role_code;    
    for i_user in (select grantee from dba_role_privs where lower(granted_role) = v_role) loop  
     counter := counter + 1;  
     v_users(counter) := i_user.grantee;  
    end loop; 
    execute immediate 'drop role "' || v_role || '"'; 
    execute immediate 'create role "' || v_role || '" not identified'; 
    for menu_ in (select menu_id from role_menu where role_code = p_role_code) 
    loop 
     v_privs := get_menu_privs(menu_.menu_id); 
     for i in v_privs.FIRST..v_privs.LAST loop 
      execute immediate 'grant ' || v_privs(i) || ' to "' || v_role || '"'; // open sql command-line connected as some username/[email protected] here to execute the grant 
     end loop; 
    end loop; 
    for i in v_users.FIRST..v_users.LAST loop 
     execute immediate 'grant "' || v_role || '" to ' || v_users(i); 
    end loop; 
end; 
/

那麼如何打開SQL命令行來執行對我評論就行了GRANT,並關閉它在該語句完成?

更新:

這裏是程序的用戶擁有者和來電:

connect system/[email protected] as sysdba 

create user pta identified by pta 
/

grant dba to pta 
/

grant create user to pta 
/

grant alter user to pta 
/

grant create role to pta 
/

grant drop any role to pta 
/

grant select on dba_role_privs to pta 
/

grant select on role_tab_privs to pta 
/

grant select on dba_roles to pta 
/
+0

通常情況下,不允許從pl sql授予權限。你有什麼例外嗎? –

+0

我在運行時遇到「權限不足」錯誤。 – pheromix

+0

他有dba的角色,它是程序本身的創建者。 – pheromix

回答

0

你必須有使授權的權力。如果程序是通過誰不具有權限的用戶擁有,那麼你必須用

AUTHID CURRENT_USER

定義,並與確實有權限的帳戶運行它。這是一個非常危險的例子,我使用這個例子允許開發人員在開發實例中訪問模​​式中的所有對象。它是允許例程工作的AUTHID CURRENT_USER。它必須由具有DBA權限的人員或架構的所有者運行:

CREATE OR REPLACE PROCEDURE grantpriv (
    p_schema   IN VARCHAR2 
    , p_role_or_person IN VARCHAR2 DEFAULT 'developer' 
    , p_permission  IN VARCHAR2 DEFAULT 'select' 
) 
    AUTHID CURRENT_USER 
AS 
    -- ########################################################################## 
    -- Grantpriv 
    -- Purpose: 
    --  Grant specified privileges to all tables in a schema 
    --  Grant select privileges to all views in a schema 
    -- Modifications: 
    --  2011.07.19 - BFL Created 
    -- ########################################################################## 
    l_sql VARCHAR2 (2000);                -- SQL statement to be executed 
    l_cnt PLS_INTEGER := 0; 

    PROCEDURE execute_sql (
     p_sql   VARCHAR2 
     , p_show_error BOOLEAN DEFAULT TRUE 
    ) 
    AS 
    BEGIN 
     EXECUTE IMMEDIATE p_sql; 

     DBMS_OUTPUT.put_line ('Executed: ' || p_sql); 
    EXCEPTION 
     WHEN OTHERS 
     THEN 
      IF p_show_error 
      THEN 
       DBMS_OUTPUT.put_line ('Error occurred executing: ' || p_sql); 
       DBMS_OUTPUT.put_line (SQLERRM); 
      END IF; 
    END execute_sql; 

    PROCEDURE put_line (p_text IN VARCHAR2) 
    AS 
    BEGIN 
     DBMS_OUTPUT.put_line (RPAD ('*', 60, '*')); 
     DBMS_OUTPUT.put_line (' ' || p_text); 
     DBMS_OUTPUT.put_line (RPAD ('*', 60, '*')); 
    END put_line; 
BEGIN 
    -- Grant permissions to tables in schema 
    FOR eachrec IN ( SELECT owner || '.' || table_name AS tname 
         FROM all_tables 
         WHERE owner = p_schema 
        ORDER BY tname) 
    LOOP 
     l_cnt := l_cnt + 1; 

     -- grant permission 
     l_sql := ' grant ' || p_permission || ' on ' || eachrec.tname || ' to ' || p_role_or_person; 

     execute_sql (l_sql); 
    END LOOP; 

    put_line (l_cnt || ' tables processed'); 
    l_cnt := 0; 

    -- Grant 'select' permission to views in schema. 
    -- It is only 'select', even if user selected other arguments. 
    FOR eachrec IN ( SELECT owner || '.' || view_name AS vname 
         FROM all_views 
         WHERE owner = p_schema 
        ORDER BY view_name) 
    LOOP 
     l_cnt := l_cnt + 1; 

     -- grant permission 
     l_sql := ' grant select on ' || eachrec.vname || ' to ' || p_role_or_person; 
     execute_sql (l_sql); 
    END LOOP; 

    put_line (l_cnt || ' views processed'); 
END; 
/