2016-07-18 1 views
1

ツールを入手返す:ヒキガエル9.7.2.5オラクル関数の戻りVARCHAR2はOKですが、SYS_REFCURSORはORA-14551

私はそれにINSERT文を持つ1つの機能を書きました。

私は、コマンド実行

SELECT TWO2F_QUERY_TEST ('XX', 'XX') 
    FROM DUAL; 

SYS_REFCURSORを返すこの関数は、私が取得するとき

1、N、* INSERT TWO2R063_W1のERROR(C1が-NOT USED)** ORA-14551 :■クエリ

varchar2を返すこの関数は、それが処理する内部でのDML操作を実行できません できuccessful

コード:

CREATE OR REPLACE FUNCTION TWO2F_QUERY_TEST 
(PI_BUS_ID   IN VARCHAR2 , 
PI_TMNL_ID  IN VARCHAR2 
)RETURN SYS_REFCURSOR IS 
--)RETURN VARCHAR2 IS 
PO_CURSOR SYS_REFCURSOR; 
WK_ACTION VARCHAR2(01) := 'Y'; 
WK_MSG VARCHAR2(100); 
BEGIN 
    BEGIN 
    INSERT INTO TWO2R063_W1 
     (R063W1_TITLE , 
     R063W1_FORWARD 
    ) 
    VALUES    
     ('PROGRAM NOT USED' , 
     'XX'    
    ) 
    ; 
    EXCEPTION 
    WHEN OTHERS THEN 
     WK_ACTION := 'N'; 
     WK_MSG := SUBSTR('*INSERT TWO2R063_W1 ERROR(C1-NOT USED)'||SQLERRM, 1, 100); 
     GOTO OUTER; 
    <<OUTER>> 
    <<ENDRTN>>         

    OPEN PO_CURSOR FOR 
    SELECT ROWNUM AS PO_ROWNUM , 
      WK_ACTION AS PO_ACTION , 
      WK_MSG AS PO_MSG 
     FROM DUAL 
    ; 

    RETURN PO_CURSOR; 

    --RETURN 'Y'; 

END TWO2F_QUERY_TEST; 

/
SHOW ERROR; 
DROP PUBLIC SYNONYM TWO2F_QUERY_TEST; 
CREATE PUBLIC SYNONYM TWO2F_QUERY_TEST FOR TWO2F_QUERY_TEST; 
GRANT EXECUTE ON TWO2F_QUERY_TEST TO GTS_AP_MAINTAIN, EGTS; 
/

======================================================== 
DROP TABLE TWO2.TWO2R063_W1 CASCADE CONSTRAINTS; 

CREATE GLOBAL TEMPORARY TABLE TWO2.TWO2R063_W1 
(R063W1_TITLE VARCHAR2(50 BYTE), 
R063W1_FORWARD VARCHAR2(20 BYTE) 
)ON COMMIT PRESERVE ROWS NOCACHE; 

DROP PUBLIC SYNONYM TWO2R063_W1; 
CREATE PUBLIC SYNONYM TWO2R063_W1 FOR TWO2.TWO2R063_W1; 
GRANT DELETE, INSERT, SELECT, UPDATE ON TWO2.TWO2R063_W1 TO TWO2_MAINTAIN; 
GRANT SELECT ON TWO2.TWO2R063_W1 TO TWO2_QUERY; 
+0

クエリで関数を参照すると、関数はデータベースの状態を変更できません。したがって、関数がDML操作を実行する場合は、問合せで使用しないでください。 –

答えて

0

あなたの最初のbeginキーワードの終了前にpragma autonomous_transactionを宣言してご覧ください。

CREATE OR REPLACE FUNCTION TWO2F_QUERY_TEST 
     (PI_BUS_ID   IN VARCHAR2 , 
     PI_TMNL_ID  IN VARCHAR2 
     )RETURN SYS_REFCURSOR IS 
     --)RETURN VARCHAR2 IS 
     PO_CURSOR SYS_REFCURSOR; 
     WK_ACTION VARCHAR2(01) := 'Y'; 
     WK_MSG VARCHAR2(100); 

     PRAGMA AUTONOMOUS_TRANSACTION; 
     BEGIN 
     -- Your code to insert 
     END 
0

私はこの問題は、あなたが戻り値のタイプではないSELECTから関数呼び出しているということだと思います。今のところDMLを削除してテストしてください。

1) SYS.DUAL 

あなたの問題は、SQLからDMLを呼び出すことである:

CREATE OR REPLACE FUNCTION TWO2F_QUERY_TEST 
RETURN SYS_REFCURSOR IS 
PO_CURSOR SYS_REFCURSOR; 
BEGIN 

    OPEN PO_CURSOR FOR 
    SELECT ROWNUM  AS PO_ROWNUM , 
      owner   AS PO_ACTION , 
      table_name AS PO_MSG 
     FROM all_tables 
    ; 

    RETURN PO_CURSOR; 
END TWO2F_QUERY_TEST; 
/


declare 
    cur SYS_REFCURSOR; 
    l_rownum number; 
    l_action varchar2(30); 
    l_msg varchar2(30); 
begin 
    cur := TWO2F_QUERY_TEST; 
    fetch cur into l_rownum, l_action, l_msg; 
    close cur; 
    dbms_output.put_line(l_rownum||') '||l_action||'.'||l_msg); 
end; 
/

はここに私の出力です: はここに私のテストです。

1)

2 DML

を除く))

3 SQL

から関数を呼び出すことが可能だ場合、自律型トランザクションにDMLをラップしないでください:あなたは、次のオプションがあります。