1

为什么我会收到以下错误?

Error starting at line 1 in command:

select FUNC from dual
Error report:
SQL Error: ORA-14551: cannot perform a DML operation inside a query 
ORA-06512: at "ANONYMOUS.FUNC", line 15
14551. 00000 -  "cannot perform a DML operation inside a query "
*Cause:    DML operation like insert, update, delete or select-for-update
           cannot be performed inside a query or under a PDML slave.
*Action:   Ensure that the offending DML operation is not performed or
           use an autonomous transaction to perform the DML operation within
           the query or PDML slave.

功能:

create or replace function FUNC
return types.ref_cursor
AS
result_set types.ref_cursor;
alarm ofalarmmessages.ALARMID% TYPE;
username ofalarmmessages.USERNAME% TYPE;
alarmmsg ofalarmmessages.ALARMMESSAGE% TYPE;
dvice ofalarmmessages.DEVICEID% TYPE;
begin
OPEN result_set FOR
       SELECT USERNAME,ALARMID,ALARMMESSAGE,DEVICEID
    FROM   ofalarmmessages where newoldflag='N';
LOOP
    FETCH  result_set into username,alarm,alarmmsg,dvice;
        update ofalarmmessages set newoldflag ='Y' where alarmid= alarm;
END LOOP;
RETURN result_set;
CLOSE result_set;
END;
/
show errors;
4

5 回答 5

7

这里有两个问题。您收到“ORA-14551”错误是因为您正在 SELECT 语句中执行您的函数,并且正如错误消息清楚地表明的那样,当函数执行 DML 时我们不能这样做。这个问题的解决方案是在 PL/SQL 或 SQL*Plus 中执行它。

另一个问题是引用游标是指向结果集的指针,只能获取一次。您的函数遍历 ref 光标,然后返回它。当您尝试对返回的 ref 游标执行某些操作时,这将导致错误,因为它不再有效。

哦,顺便说一句,函数中 RETURN 语句之后的任何代码都不会被执行。

于 2011-09-05T13:07:34.117 回答
3

您可以避免在 SELECT 语句中使用该函数,如下所示:

var rc refcursor
exec :rc := func;
于 2011-09-05T11:35:30.937 回答
2

你可以叫它

SET SERVEROUTPUT ON
EXEC DBMS_OUTPUT.PUT_LINE(your_fn_name(your_fn_arguments))
于 2013-11-13T13:59:43.323 回答
1

您可以通过执行简单的更新查询来实现上述内容:

update ofalarmmessages 
set newoldflag='Y'
where newoldflag='N';

你真的必须有一个功能吗?

于 2011-09-05T17:19:44.150 回答
0

您添加“ PRAGMA AUTONOMOUS_TRANSACTION”进行更新

create or replace function FUNC
return types.ref_cursor
PRAGMA AUTONOMOUS_TRANSACTION;
/* ... */

试试看

于 2014-03-20T03:51:50.603 回答