programing

"쿼리 내에서 DML 작업을 수행할 수 없음"에 대한 솔루션?

itmemos 2023. 6. 26. 21:04
반응형

"쿼리 내에서 DML 작업을 수행할 수 없음"에 대한 솔루션?

저는 데이터 분석 도구를 사용하고 있으며, 사용자로부터 값을 받아 매개 변수로 전달하고 테이블에 저장해야 합니다.꽤 솔직해서 이걸 쓰려고 앉았어요.

create or replace
procedure complex(datainput in VARCHAR2)
is
begin
insert into dumtab values (datainput);
end complex;

다음 문장을 사용하여 SQL Developer에서 실행했습니다.

begin
complex('SomeValue');  
end;

그것은 잘 작동했고, 그 값은 표에 삽입되었습니다.그러나 위의 문장은 Data Analysis 툴에서 지원되지 않기 때문에 함수를 사용하기로 했습니다.다음은 함수의 코드입니다. 함수를 컴파일합니다.

create or replace
function supercomplex(datainput in VARCHAR2)
return varchar2
is
begin
insert into dumtab values (datainput);
return 'done';
end supercomplex;   

다시 한번 SQL Developer에서 실행하려고 했지만 다음 코드를 실행할 때 쿼리 내에서 DML 작업을 수행할 수 없습니다.

select supercomplex('somevalue') from dual;

질문은 - SQL Developer에서 언급된 기능을 실행할 수 있는 문이 필요하거나 - select 문으로 실행할 수 있는 내가 찾고 있는 것을 실행할 수 있는 기능 - 만약 내가 요청한 것을 수행할 수 없다면, 나는 매니저에게 내가 매우 새로운 (일주일 정도?) PL/SQL로 이동하여 규칙과 구문을 알지 못합니다.

추신: 이것이 C++ 또는 심지어 자바였으면 얼마나 좋을까요 :(

편집

DMine(도구)에서 실행하기 전에 SQL Developer에서 해당 기능이 유효한지 테스트하기 위해 실행해야 합니다.SQL에서 유효하지 않은 항목은 DMine에서도 유효하지 않지만, 그 반대는 아닙니다.

도와주셔서 감사합니다. 상황과 불법/권장되지 않는 이유를 이해했습니다.

지침을 사용할 수 있습니다.pragma autonomous_transaction이렇게 하면 ORA-14551을 올리지 않고 DML을 수행할 수 있는 독립적인 트랜잭션으로 기능이 실행됩니다.

자율 트랜잭션은 독립적이기 때문에 DML의 결과는 상위 트랜잭션의 범위 밖에서 커밋됩니다.대부분의 경우 이는 허용 가능한 해결 방법이 아닙니다.

SQL> CREATE OR REPLACE FUNCTION supercomplex(datainput IN VARCHAR2)
  2     RETURN VARCHAR2 IS
  3     PRAGMA AUTONOMOUS_TRANSACTION;
  4  BEGIN
  5     INSERT INTO dumtab VALUES (datainput);
  6     COMMIT;
  7     RETURN 'done';
  8  END supercomplex;
  9  /

Function created

SQL> SELECT supercomplex('somevalue') FROM dual;

SUPERCOMPLEX('SOMEVALUE')
--------------------------------------------------------------------------------
done

SQL> select * from dumtab;

A
--------------------------------------------------------------------------------
somevalue

Tom Kyte는 애초에 오류가 발생한 이유에 대해 좋은 설명을 합니다.행이 처리되는 순서에 따라 달라질 수 있으므로 안전하지 않습니다.또한 Oracle은 이 기능이 행당 최소 한 번 및 최대 한 번 실행된다고 보장하지 않습니다.

반환 값을 수락할 변수를 선언하기만 하면 됩니다. 예:

declare
    retvar varchar2(4);
begin
    retvar := supercomplex('somevalue');
end;

함수가 삽입을 수행하고 있기 때문에 선택이 작동하지 않습니다. 함수가 값만 반환하면 선택이 작동합니다.

▁a▁▁the다▁dummy니▁just▁executeif ... end if;반환 값을 무시하는 문:

exec if supercomplex('somevalue') then null; end if;

또다음대매변실행합다니수로개한는에에 대한 합니다.put_line반환 값을 출력하는 절차:

exec dbms_ouput ('result of supercomplex='||supercomplex('somevalue'));

result of supercomplex=done

언급URL : https://stackoverflow.com/questions/8729236/solution-to-cannot-perform-a-dml-operation-inside-a-query

반응형