Plsql 如何从存储过程启动SQL命令行?

Plsql 如何从存储过程启动SQL命令行?,plsql,oracle11gr2,Plsql,Oracle11gr2,我想直接授予,因为不允许从PLSQL授予。以下是我的存储过程: connect pta/pta@xe 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_integ

我想直接授予,因为不允许从PLSQL授予。以下是我的存储过程:

connect pta/pta@xe

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/password@someinstance 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;
/
connect system/a@xe 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
/
那么,如何打开sql命令行在我注释的行上执行授权,并在语句完成时关闭它呢

更新:

以下是过程的用户所有者和调用方:

connect pta/pta@xe

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/password@someinstance 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;
/
connect system/a@xe 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
/

你必须有权发放补助金。如果该过程由没有该权限的用户拥有,则必须使用

authid当前用户

并使用具有权限的帐户运行它。下面是一个非常危险的示例,我使用它来允许开发实例上的开发人员访问模式中的所有对象。允许例程工作的是AUTHID当前用户。它必须由具有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;
/

通常,不允许从pl sql进行授权是不正确的。您是否有任何异常。我在运行时遇到“权限不足”错误。他是dba角色,是过程本身的创建者。为什么您不能以注释的形式登录用户并运行此脚本。奇怪的是,登录为
pta
select*from session\u角色