트리거에서 변경 테이블 오류가 발생하지 않는 이유는 무엇입니까?


11

트리거 내부의 돌연변이 테이블에서 DML 문을 사용할 수없는 것으로 알려져 있습니다. 오라클 문서 에서 발췌 :

변경 테이블은 UPDATE, DELETE 또는 INSERT 문으로 수정중인 테이블 또는 DELETE CASCADE 제한 조건의 영향으로 업데이트 될 수있는 테이블입니다.

트리거 명령문을 발행 한 세션은 변경 테이블을 조회하거나 수정할 수 없습니다. 이 제한은 트리거가 일치하지 않는 데이터 세트를 보지 못하게합니다.

그러나 insert into empSQL Developer 또는 SQL * Plus를 사용하여 수행 할 때이 데모 트리거가 "돌연변이 테이블"오류로 실패하지 않는 이유를 이해할 수 없습니다 .

CREATE OR REPLACE TRIGGER emp_bri   
  BEFORE INSERT ON emp 
    FOR EACH ROW
BEGIN

  SELECT max(id) + 1 INTO :NEW.id FROM emp;
  UPDATE emp SET salary = 5000;

END emp_bri;

다음 id값 으로 삽입이 완료 되고 모든 emp레코드가 업데이트됩니다 . Oracle Database 11g Enterprise Edition 릴리스 11.2.0.1.0을 사용하고 있습니다. 복합 트리거에 대해 읽었지만 샘플에서 사용하지 않습니다.


1
귀하의 질문과 관련이 없지만 고유 번호를 할당 하는 데 사용 하지 마십시오select max(id) . 하지마 그것은 단순히 틀리며 확장되지 않습니다.
a_horse_with_no_name

예, 나는 알고 있습니다 :)이 경우에는 예제가 좋지 않을 것입니다 ... 시퀀스와 트리거를 사용하여 자동 증가 값을 확실히 구현해야합니다.
센츄리

이것은 확실하다. Btw : 다음은 SQLFiddle 예제입니다 sqlfiddle.com/#!4/9e59f/2
a_horse_with_no_name

정보 공유, 멋진 링크 감사합니다. 오라클 SQL 테스트 웹 사이트 : 거기 몰랐
백부장

a_horse_with_no_name : 다른 예 : Fiddle-test-2 (SET salary = salary + 10)
ypercubeᵀᴹ

답변:


12

예외가 있습니다. before insert테이블에서, 행 레벨 트리거 를 정의하고 단일 행 INSERT명령문을 발행 하면 table is mutating오류가 발생하지 않습니다. 그러나 동일한 종류의 트리거를 정의하고 여러 행 INSERT명령문을 발행 하면 오류가 발생합니다. 예를 들면 다음과 같습니다.

SQL> create table TB_TR_TEST(
  2    col1 number,
  3    col2 number
  4  )
  5  ;

Table created

SQL> create or replace trigger TR_TB_TR_TEST
  2  before insert on TB_TR_TEST
  3  for each row
  4  begin
  5    SELECT max(col1) + 1 INTO :NEW.col1
  6      FROM TB_TR_TEST;
  7    UPDATE TB_TR_TEST SET col2 = 5000;
  8  end;
  9  /

Trigger created

다음은 단일 행 insert명령문으로, 돌연변이 테이블 오류가 발생하지 않습니다.

SQL> insert into TB_TR_TEST(col1, col2) values(1,2);

1 row inserted

SQL> insert into TB_TR_TEST(col1, col2) values(3,5);

1 row inserted

SQL> commit;

Commit complete

다음은 다중 행 삽입 명령문으로, 변경 테이블 오류가 발생합니다.

SQL> insert into TB_TR_TEST(col1, col2)
  2    select 1, 2
  3      from dual;

insert into TB_TR_TEST(col1, col2)
  select 1, 2
    from dual

ORA-04091: table HR.TB_TR_TEST is mutating, trigger/function may not see it
ORA-06512: at "HR.TR_TB_TR_TEST", line 2
ORA-04088: error during execution of trigger 'HR.TR_TB_TR_TEST'

그것은 범인 인 것 같습니다. 이 동작에 대한 매뉴얼을 참조하십니까?
a_horse_with_no_name

@a_horse_with_no_name support.oracle.com에 액세스 할 수 있으면 ID 132569.1( ORA-4091 on BEFORE ROW TRIGGER with INSERT .. into SELECT statement)을 검색하십시오 .
니콜라스 크라스 노프

2
감사. 재미있는만큼이 예외 만 8i를에 설명 할 것으로 보인다 설명서를 (!) : docs.oracle.com/cd/F49540_01/DOC/server.815/a68003/...를 (섹션 " "돌연변이 및 구속 테이블 ") 내가 할 수있는 ' 현재 매뉴얼에서 그 내용을 찾을 수 없음
a_horse_with_no_name
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.