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

时间:2017-03-01 06:39:14

标签: plsql oracle11gr2

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

var rawData = "BEGIN:VEVENT\r\nDTSTART;TZID=America/New_York:20161231T123000\r\nDTEND;TZID=America/New_York:20161231T133000\r\nRRULE:FREQ=WEEKLY;UNTIL=20170211T045959Z;BYDAY=SA\r\nDTSTAMP:20170228T012109Z\r\nUID:h742jrf72h1r4oferera9dp070@google.com\r\nCREATED:20170102T190437Z\r\nDESCRIPTION:\r\nLAST-MODIFIED:20170211T152911Z\r\nLOCATION:\r\nSEQUENCE:0\r\nSTATUS:CONFIRMED\r\nSUMMARY:happy\r\nTRANSP:OPAQUE\r\nEND:VEVENT\r\nBEGIN:VEVENT\r\nDTSTART;TZID=America/New_York:20170106T170000\r\nDTEND;TZID=America/New_York:20170106T173000\r\nRRULE:FREQ=WEEKLY;BYDAY=FR\r\nDTSTAMP:20170228T012109Z\r\nUID:ukad1og7htm89pc8j4di4otlk8_R20170106T220000@google.com\r\nCREATED:20141126T041733Z\r\nDESCRIPTION:\r\nLAST-MODIFIED:20170120T210013Z\r\nLOCATION:sds\r\nSEQUENCE:0\r\nSTATUS:CONFIRMED\r\nSUMMARY:Gold/Blue/Green Weapons\r\nTRANSP:OPAQUE\r\nBEGIN:VALARM\r\nACTION:NONE\r\nTRIGGER;VALUE=DATE-TIME:19760401T005545Z\r\nEND:VALARM\r\nEND:VEVENT\r\nBEGIN:VEVENT\r\nDTSTART;TZID=America/New_York:20161229T160000\r\nDTEND;TZID=America/New_York:20161229T164500\r\nDTSTAMP:20170228T012109Z\r\nUID:8thf9943qdnjkcrtlvt6k8kjmg@google.com\r\nRECURRENCE-ID;TZID=America/New_York:20161229T160000\r\nCREATED:20160612T220329Z\r\nDESCRIPTION:\r\nLAST-MODIFIED:20170117T200013Z\r\nLOCATION:\r\nSEQUENCE:0\r\nSTATUS:CONFIRMED\r\nSUMMARY:Juniors school\r\nTRANSP:OPAQUE\r\nBEGIN:VALARM\r\nACTION:NONE\r\nTRIGGER;VALUE=DATE-TIME:19760401T005545Z\r\nEND:VALARM\r\nEND:VEVENT\r\n"

function rawToJSON(raw) {

  var arr = [];
  var lines = raw.split('\r\n');

  lines.reduce(function(obj, line){

    var keyValue = line.split(":");
    var key = keyValue[0];
    var value = keyValue[1];

    Object.assign(obj, {[key]: value});

    if (key == 'END' && value == 'VEVENT') {
      arr.push(obj);
      return {};
    }

    return obj;

  }, {});

  return arr;

}

console.log(rawToJSON(rawData));

那么如何在我评论的行上打开sql命令行来执行GRANT,并在语句完成后关闭它?

更新:

这是程序的用户所有者和调用者:

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

1 个答案:

答案 0 :(得分: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;
/