工具:Toad 9.7.2.5
我写了一个函数,里面有一个insert语句。
我执行命令
SELECT TWO2F_QUERY_TEST ('XX', 'XX')
FROM DUAL;
当这个函数返回SYS_REFCURSOR
时,我会得到
1,N,* INSERT TWO2R063_W1错误(C1-NOT USED)** ORA-14551:不能 在查询中执行DML操作
当此函数返回varchar2
时,它将处理成功的
代码:
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 :(得分:0)
在您的第一个pragma autonomous_transaction
关键字结束之前声明begin
并查看。
示例强>
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
答案 1 :(得分: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包装成自治事务。