ORA-29471:DBMS_SQL 访问被拒绝;详细信息:ORA-06512:位于“SYS.DBMS_SQL”,第 1199 行

问题描述 投票:0回答:1

我在包内定义了 2 个过程 procA 和 procB。我正在尝试从 ProcA 调用 procB。 procB 使用 DBMS_SQL.PARSE & EXECUTE 等来执行 SQL 语句。单独运行时 procB 按预期工作 procB 失败并显示

ORA-29471:从 procA 调用时 DBMS_SQL 访问被拒绝

CREATE OR REPLACE PACKAGE BODY PKG_R3_ADV_FILTER
as
PROCEDURE P_GET_FILE(
    PO_R3FILTERRECORDS   OUT SYS_REFCURSOR,
    PO_MEDDRA_CONFIG     OUT SYS_REFCURSOR)
    AS
    V_SEL          VARCHAR2 (20000);
    V_FRM          VARCHAR2 (20000);
    V_WRY          VARCHAR2 (20000);
    V_OTHER        VARCHAR2 (20000);
    V_MAIN         CLOB;
    V_FILTER       CLOB;
    V_FILTER_PARAM CLOB;
    GV_FROM_DATE   DATE := TO_DATE (sysdate, 'DD-MON-YYYY');
    GV_TO_DATE     DATE := TO_DATE (sysdate, 'DD-MON-YYYY') + 1;
    --V_MEDDRA_CONFIG CHAR(1):='N';
    V_FN_CNT       NUMBER;
    EXP_SQL_INJECTION       EXCEPTION;
    RETURN_NO VARCHAR2(4000);
    
    BEGIN
            V_FILTER := 'lower(event_country) = :event_country_1';
            V_FILTER_PARAM := '{"event_country_1":"de"}';
        
        GV_MEDDRA_CONFIG := 'N';

    V_SEL:= 'WITH PARAM AS (SELECT :P1 V_FROM_DATE,:P2 V_TO_DATE, :P3 V_MEDDRA_CONFIG FROM DUAL),
    CFG_FILES
    AS
    (   SELECT FILES.USER_ID USER_ID_USR, USR.USER_FULLNAME USER_NAME, FILES.*,A.V_FROM_DATE,A.V_TO_DATE
    FROM E2B_R3_CFG_FILES FILES, E2B_CFG_USERS USR, PARAM A
    WHERE FILES.USER_ID = USR.USER_ID(+) AND TRUNC(FILES.PROCESSED_DATE_GMT) >= A.V_FROM_DATE AND TRUNC(FILES.PROCESSED_DATE_GMT) < A.V_TO_DATE
    )
    SELECT FILES.FILE_ID,
    FILES.FILE_NAME,
    FILES.SAFETY_REPORT_ID,
    FILES.PRIM_RPT_COUNTRY,
    FILES.PRODUCT_NAME AS PROD_NAME,
    FILES.FORMULATION,
    FILES.ACTIVE_SUBSTANCE as ACTIVE_SUB,
    FILES.PRODUCT_NAME_NULL,
    FILES.FORMULATION_NULL,
    FILES.ACTIVE_SUBSTANCE_NULL,
    FILES.DATE_REPORTED,
    FILES.DATE_MOST_RECENT,
    FILES.PAT_ADMIN_ROUTE,
    FILES.EVENT_COUNTRY,
    FILES.E2B_COMP_NUM,
    FILES.E2B_DUP_NUM,
    FILES.PROCESSED_DATE,
    DECODE (FILES.IS_RULE_PASSED,  0, ''No'',  1, ''Yes'',  2, ''NA'')
    IS_RULE_PASSED,
    FILES.JUST_COMMENTS,
    /*DECODE (ACTION_TAKEN,  0, ''NONE'',  1, ''ACCEPT'',  2, ''REJECT'')*/
    (SELECT FLAGVALUE12 FROM E2B_CMN_FLAG_LOOKUP WHERE ID = FILES.ACTION_TAKEN) ACTION_TAKEN,
    FILES.USER_ID_USR USER_ID,
    FILES.IS_MOVED,
    FILES.MODIFIED_DATE,
    DECODE (FILES.PREVIOUS_ACTION,  0, ''None'',  1, ''Accept'',  2, ''Reject'')
    PREVIOUS_ACTION,
    /*DECODE (IS_CASE_SERIOUS,  0, ''NO'',  1, ''YES'',  2, ''FATAL'')*/
    (SELECT FLAGVALUE7 FROM E2B_CMN_FLAG_LOOKUP WHERE ID = to_char(FILES.IS_CASE_SERIOUS))
    IS_CASE_SERIOUS,
    FILES.USER_NAME,
    (CASE WHEN DBMS_LOB.GETLENGTH(FILES.LITERATURE_REFERENCE)>2000
    THEN CAST (DBMS_LOB.SUBSTR (FILES.LITERATURE_REFERENCE, 2000, 1) AS VARCHAR2 (4000))||''[...Data Truncated]''
    ELSE CAST (DBMS_LOB.SUBSTR (FILES.LITERATURE_REFERENCE, 2000, 1) AS VARCHAR2 (4000))
    END)
    LITERATURE_REFERENCE,
    FILES.HTML_VW_GENERATED,
    (CASE A.V_MEDDRA_CONFIG WHEN ''N'' THEN ''NA'' ELSE FILES.MEDDRA_CRITICAL_TERM END) MEDDRA_CRITICAL_TERM';
    V_FRM:=' FROM CFG_FILES FILES,
    PARAM A';
    /*V_WRY:=' WHERE FILES.FILE_ID = PROD.FILE_ID(+)
    AND   FILES.FILE_ID = FRM.FILE_ID(+)
    AND   FILES.FILE_ID = FRM_N.FILE_ID(+)
    AND   FILES.FILE_ID = ACT.FILE_ID(+)
    AND   FILES.FILE_ID = ACT_N.FILE_ID(+)';*/
    
    V_MAIN:='SELECT * FROM ('||V_SEL||V_FRM||V_WRY||') WHERE '||V_FILTER;
    
    V_FN_CNT:=PKG_COMMON_UTILITIES.FN_SEARCH_KEYWORD(V_FILTER);
    
    IF V_FN_CNT = 1 THEN
        RAISE EXP_SQL_INJECTION;
    END IF;
    
    IF V_FILTER_PARAM IS NOT NULL THEN 
        PKG_R3_ADV_FILTER.P_FILTER_SQL_INJ(V_MAIN,V_FILTER_PARAM);
    END IF;
    
    BEGIN
        IF V_FILTER_PARAM IS NULL THEN 
            OPEN PO_R3FILTERRECORDS FOR V_MAIN USING GV_FROM_DATE, GV_TO_DATE, GV_MEDDRA_CONFIG;
        ELSE 
            OPEN PO_R3FILTERRECORDS FOR SELECT * FROM GT_R3_ADV_FILTER;
        END IF;
        OPEN PO_MEDDRA_CONFIG FOR SELECT GV_MEDDRA_CONFIG MEDDRA_CONFIG FROM DUAL;
        PO_ERROR_CODE := 0;
        PO_ERROR_MSG := 'Success';
    EXCEPTION
    WHEN EXP_SQL_INJECTION THEN
        dbms_output.put_line(sqlerrm);
    WHEN OTHERS THEN
        dbms_output.put_line(sqlerrm);
    END;
    EXCEPTION
    WHEN OTHERS THEN
        dbms_output.put_line(sqlerrm);
    END;
PROCEDURE P_FILTER_SQL_INJ
    (
        PI_TEMPFILTER        IN CLOB,
        PI_TEMPFILTERPARAMS  IN CLOB
    )
    IS
    TYPE TYP_FILE_ID IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_FILE_ID TYP_FILE_ID;
    TYPE TYP_FILE_NAME IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_FILE_NAME TYP_FILE_NAME;
    TYPE TYP_SAFETY_REPORT_ID IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_SAFETY_REPORT_ID TYP_SAFETY_REPORT_ID;
    TYPE TYP_PRIM_RPT_COUNTRY IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_PRIM_RPT_COUNTRY TYP_PRIM_RPT_COUNTRY;
    TYPE TYP_PROD_NAME IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_PROD_NAME TYP_PROD_NAME;
    TYPE TYP_FORMULATION IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_FORMULATION TYP_FORMULATION;
    TYPE TYP_ACTIVE_SUB IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_ACTIVE_SUB TYP_ACTIVE_SUB;
    TYPE TYP_PROD_NAME_NULL IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_PROD_NAME_NULL TYP_PROD_NAME_NULL;
    TYPE TYP_FORMULATION_NULL IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_FORMULATION_NULL TYP_FORMULATION_NULL;
    TYPE TYP_ACTIVE_SUB_NULL IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_ACTIVE_SUB_NULL TYP_ACTIVE_SUB_NULL;
    TYPE TYP_DATE_REPORTED IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_DATE_REPORTED TYP_DATE_REPORTED;
    TYPE TYP_DATE_MOST_RECENT IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_DATE_MOST_RECENT TYP_DATE_MOST_RECENT;
    TYPE TYP_PAT_ADMIN_ROUTE IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_PAT_ADMIN_ROUTE TYP_PAT_ADMIN_ROUTE;
    TYPE TYP_EVENT_COUNTRY IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_EVENT_COUNTRY TYP_EVENT_COUNTRY;
    TYPE TYP_E2B_COMP_NUM IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_E2B_COMP_NUM TYP_E2B_COMP_NUM;
    TYPE TYP_E2B_DUP_NUM IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_E2B_DUP_NUM TYP_E2B_DUP_NUM;
    TYPE TYP_PROCESSED_DATE IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_PROCESSED_DATE TYP_PROCESSED_DATE;
    TYPE TYP_IS_RULE_PASSED IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_IS_RULE_PASSED TYP_IS_RULE_PASSED;
    TYPE TYP_JUST_COMMENTS IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_JUST_COMMENTS TYP_JUST_COMMENTS;
    TYPE TYP_ACTION_TAKEN IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_ACTION_TAKEN TYP_ACTION_TAKEN;
    TYPE TYP_USER_ID IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_USER_ID TYP_USER_ID;
    TYPE TYP_IS_MOVED IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_IS_MOVED TYP_IS_MOVED;
    TYPE TYP_MODIFIED_DATE IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_MODIFIED_DATE TYP_MODIFIED_DATE;
    TYPE TYP_PREVIOUS_ACTION IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_PREVIOUS_ACTION TYP_PREVIOUS_ACTION;
    TYPE TYP_IS_CASE_SERIOUS IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_IS_CASE_SERIOUS TYP_IS_CASE_SERIOUS;
    TYPE TYP_USER_NAME IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_USER_NAME TYP_USER_NAME;
    TYPE TYP_LITERATURE_REFERENCE IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_LITERATURE_REFERENCE TYP_LITERATURE_REFERENCE;
    TYPE TYP_HTML_VW_GENERATED IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_HTML_VW_GENERATED TYP_HTML_VW_GENERATED;
    TYPE TYP_MEDDRA_CRITICAL_TERM IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
    TAB_MEDDRA_CRITICAL_TERM TYP_MEDDRA_CRITICAL_TERM;
    TYPE CURTYPE IS REF CURSOR;
    
    SRC_CUR     SYS_REFCURSOR;
    KEYS_STRING     CLOB;
    KEYS_VALUE      CLOB;
    V_KEYS_STRING   VARCHAR2(32000);
    V_KEYS_VALUE    VARCHAR2(32000);
    V_CURSOR        PLS_INTEGER;
    V_RESULT        PLS_INTEGER;
    JSNOBJ          JSON_OBJECT_T;
    V_KEYS          JSON_KEY_LIST;
    PO_ERROR_CODE   VARCHAR2(4000);
    PO_ERROR_MSG    VARCHAR2(4000);
    
    --MY_QUERY_STR  RAHUL_TEST.FILTER_JSON%TYPE;
    --JSONARR     JSON_ARRAY_T;
    --JV          JSON_ARRAY_T;
    
BEGIN
    
    --JA := NEW JSON_ARRAY_T;
    --JV := NEW JSON_ARRAY_T;
    JSNOBJ := JSON_OBJECT_T.PARSE(PI_TEMPFILTERPARAMS);
    V_KEYS    := JSNOBJ.GET_KEYS;
    
**/*getting the error in the below line*/**
    DBMS_SQL.PARSE(V_CURSOR, PI_TEMPFILTER, DBMS_SQL.NATIVE);
    
    DBMS_SQL.BIND_VARIABLE(V_CURSOR, 'P1', GV_FROM_DATE);
    DBMS_SQL.BIND_VARIABLE(V_CURSOR, 'P2', GV_TO_DATE);
    DBMS_SQL.BIND_VARIABLE(V_CURSOR, 'P3', GV_MEDDRA_CONFIG);
    FOR I IN 1..V_KEYS.COUNT LOOP
        V_KEYS_STRING:=V_KEYS(I);
        IF JSNOBJ.GET_STRING (V_KEYS(I)) IS NOT NULL 
        THEN
            V_KEYS_VALUE:= JSNOBJ.GET_STRING (V_KEYS(I));
        ELSIF JSNOBJ.GET_NUMBER (V_KEYS(I)) IS NOT NULL 
        THEN
            V_KEYS_VALUE:= JSNOBJ.GET_NUMBER (V_KEYS(I));
        END IF;
        DBMS_SQL.BIND_VARIABLE(V_CURSOR, V_KEYS_STRING, V_KEYS_VALUE);
    END LOOP;
    
--  DELETE FROM GT_INPUT_PARAMETERS;
--  INSERT INTO GT_INPUT_PARAMETERS(PARACLOB1,PARACLOB2) VALUES(V_KEYS_STRING,V_KEYS_VALUE);
--  
--  FOR J IN(SELECT PARACLOB1,PARACLOB2 FROM GT_INPUT_PARAMETERS)LOOP
--      DBMS_SQL.BIND_VARIABLE(MY_CURSOR, J.PARACLOB1, J.PARACLOB2);
--  END LOOP;
    
    --KEYS_STRING := JA.TO_STRING;
    --KEYS_VALUE  := JV.TO_STRING;
    
    V_RESULT   := DBMS_SQL.EXECUTE(V_CURSOR);
    
    SRC_CUR     := DBMS_SQL.TO_REFCURSOR(V_CURSOR);
    
    FETCH SRC_CUR BULK COLLECT INTO 
        TAB_FILE_ID,              TAB_FILE_NAME,              TAB_SAFETY_REPORT_ID,     TAB_PRIM_RPT_COUNTRY,
        TAB_PROD_NAME,            TAB_FORMULATION,            TAB_ACTIVE_SUB,           TAB_PROD_NAME_NULL,
        TAB_FORMULATION_NULL,     TAB_ACTIVE_SUB_NULL,        TAB_DATE_REPORTED,        TAB_DATE_MOST_RECENT,
        TAB_PAT_ADMIN_ROUTE,      TAB_EVENT_COUNTRY,          TAB_E2B_COMP_NUM,         TAB_E2B_DUP_NUM,
        TAB_PROCESSED_DATE,       TAB_IS_RULE_PASSED,         TAB_JUST_COMMENTS,        TAB_ACTION_TAKEN,
        TAB_USER_ID,              TAB_IS_MOVED,               TAB_MODIFIED_DATE,        TAB_PREVIOUS_ACTION,
        TAB_IS_CASE_SERIOUS,      TAB_USER_NAME,              TAB_LITERATURE_REFERENCE, TAB_HTML_VW_GENERATED,
        TAB_MEDDRA_CRITICAL_TERM;
        
    FOR H IN 1..TAB_FILE_ID.COUNT 
    LOOP
        INSERT INTO GT_R3_ADV_FILTER
        (
            FILE_ID,              FILE_NAME,                SAFETY_REPORT_ID,       PRIM_RPT_COUNTRY,
            PRODUCT_NAME,         FORMULATION,              ACTIVE_SUBSTANCE,       PRODUCT_NAME_NULL,
            FORMULATION_NULL,     ACTIVE_SUBSTANCE_NULL,    DATE_REPORTED,          DATE_MOST_RECENT,
            PAT_ADMIN_ROUTE,      EVENT_COUNTRY,            E2B_COMP_NUM,           E2B_DUP_NUM,
            PROCESSED_DATE,       IS_RULE_PASSED,           JUST_COMMENTS,          ACTION_TAKEN,
            USER_ID,              IS_MOVED,                 MODIFIED_DATE,          PREVIOUS_ACTION,
            IS_CASE_SERIOUS,      USER_NAME,                LITERATURE_REFERENCE,   HTML_VW_GENERATED,
            MEDDRA_CRITICAL_TERM
        ) 
        VALUES
        (
            TAB_FILE_ID(H),           TAB_FILE_NAME(H),         TAB_SAFETY_REPORT_ID(H),        TAB_PRIM_RPT_COUNTRY(H),
            TAB_PROD_NAME(H),         TAB_FORMULATION(H),       TAB_ACTIVE_SUB(H),              TAB_PROD_NAME_NULL(H),
            TAB_FORMULATION_NULL(H),  TAB_ACTIVE_SUB_NULL(H),   TAB_DATE_REPORTED(H),           TAB_DATE_MOST_RECENT(H),
            TAB_PAT_ADMIN_ROUTE(H),   TAB_EVENT_COUNTRY(H),     TAB_E2B_COMP_NUM(H),            TAB_E2B_DUP_NUM(H),
            TAB_PROCESSED_DATE(H),    TAB_IS_RULE_PASSED(H),    TAB_JUST_COMMENTS(H),           TAB_ACTION_TAKEN(H),
            TAB_USER_ID(H),           TAB_IS_MOVED(H),          TAB_MODIFIED_DATE(H),           TAB_PREVIOUS_ACTION(H),
            TAB_IS_CASE_SERIOUS(H),   TAB_USER_NAME(H),         TAB_LITERATURE_REFERENCE(H),    TAB_HTML_VW_GENERATED(H),
            TAB_MEDDRA_CRITICAL_TERM(H)
        );
    END LOOP;
    --CLOSE SRC_CUR;
    EXCEPTION
    WHEN OTHERS THEN
        dbms_output.put_line(sqlerrm);
    END;
end;
/
sql oracle plsql
1个回答
0
投票

您的问题中有太多代码需要分析。也许使用 DBMS_SQL 包的基本原则可以帮助您找到所提供的代码的方法。
这是创建 SYS_REFCURSOR 供外部使用的过程...

CREATE OR REPLACE PROCEDURE TESTPROC 
 AS 
  V_CURSOR SYS_REFCURSOR;
BEGIN
  OPEN V_CURSOR FOR
  SELECT 1 "A_NUMBER", 'A' "A_LETTER" FROM Dual UNION ALL
  SELECT 2 "A_NUMBER", 'B' "A_LETTER" FROM Dual;
  
  DBMS_SQL.RETURN_RESULT(V_CURSOR);
END TESTPROC;

...以及另一个使用第一个结果集的过程 - 也使用 DBMS_SQL 包...(代码中的注释)

SET SERVEROUTPUT ON
DECLARE
  p_sql_cursor    PLS_INTEGER;
  p_ref_cursor    SYS_REFCURSOR;
  p_return        PLS_INTEGER;
  p_number        NUMBER(6);
  p_letter        VARCHAR2(12);
BEGIN
    -- 1. Initialize cursor with DBMS_SQL.open_cursor()
    p_sql_cursor := DBMS_SQL.open_cursor(treat_as_client_for_results => TRUE);
    
    -- 2. Parse TESTPROC Using DBMS_SQL.parse()
    DBMS_SQL.parse(c             => p_sql_cursor,           -- <--- parse to cursor initialized in step 1.
                   statement     => 'BEGIN TESTPROC; END;', -- <--- running first procedure as PL/SQL Block to get cursor
                   language_flag => DBMS_SQL.native);
    -- 3. Execute cursor initialized in step 1. (with parsed cursor from step 2.)
    p_return := DBMS_SQL.execute(p_sql_cursor);       
    -- 4. Get the resultset and process it ...
    BEGIN
      DBMS_SQL.get_next_result(p_sql_cursor, p_ref_cursor);
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        Null;
    END;
      --  Processing it
        LOOP
          FETCH p_ref_cursor
          INTO  p_number, p_letter;

          EXIT WHEN p_ref_cursor%NOTFOUND;

          DBMS_OUTPUT.put_line('p_number=' || p_number || '  ' ||
                               'p_letter=' || p_letter);
        END LOOP;
        CLOSE p_ref_cursor;
END;
/
/*    R e s u l t :
p_number=1  p_letter=A
p_number=2  p_letter=B

PL/SQL procedure successfully completed.    */

作为替代方案,您可以仅执行过程 (SQLDeveloper) 来获取结果集:

EXEC TESTPROC;
/*    R e s u l t :
  A_NUMBER A_LETTER
---------- --------
         1 A
         2 B        */
© www.soinside.com 2019 - 2024. All rights reserved.