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

ここには 2 つの問題があります。「ORA-14551」エラーが発生するのは、関数を SELECT ステートメントで実行しているためです。エラー メッセージが明確に示しているように、関数が DML を実行するときにこれを行うことはできません。この問題の解決策は、PL/SQL または SQL*Plus で実行することです。

もう 1 つの問題は、ref カーソルが結果セットへのポインターであり、一度しかフェッチできないことです。関数は ref カーソルを反復処理してから返します。これにより、返された ref カーソルを使用して何かを実行しようとすると、エラーが発生します。これは、無効になっているためです。

ところで、関数内の RETURN ステートメントに続くコードは実行されません。

于 2011-09-05T13:07:34.117 に答える
3

次のように、SELECT ステートメントで関数を使用することを避けることができます。

var rc refcursor
exec :rc := func;
于 2011-09-05T11:35:30.937 に答える
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 に答える