2016-07-18 21 views
1

工具:蟾蜍9.7.2.5Oracle函數返回VARCHAR2是好的,但返回SYS_REFCURSOR得到ORA-14551

我寫了1個功能,具有插入語句它。

我執行命令

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

當此功能,它返回SYS_REFCURSOR,我將得到

1,N,* INSERT TWO2R063_W1 ERROR(C1-未使用)** ORA-14551 :不能 查詢

當此功能,它返回varchar2,它將處理內執行DML供電S 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並測試它。 這裏是我的測試:

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) SYS.DUAL 

您的問題是從SQL調用DML。您有以下選項:

1)刪除DML

2)不要從SQL

3調用功能)包裝成DML自治事務,如果可能的。