데이터베이스 연구실.log

변경 이력과 입력값 처리

행 트리거의 :OLD와 :NEW, DML 이력의 ROLLBACK 동작 및 이행 시 입력값 처리 비교

감사 이력AFTER 트리거NVL(:NEW, :OLD)트랜잭션ROLLBACKORA-04092BEFORE 행 트리거기본값 대입AUTO_INCREMENT

#핵심 요약

INSERT에는 바뀌기 전 값(:OLD)이 없어 old_sal이 비고, DELETE에는 바뀐 뒤 값(:NEW)이 없어 new_sal이 빔
그래서 empno, ename은 NVL(:NEW.x, :OLD.x)로 있는 쪽을 씀

트리거가 넣은 이력은 사용자 DML과 같은 트랜잭션임
사용자가 ROLLBACK하면 이력도 함께 취소되고, 트리거 안에는 COMMIT을 넣을 수 없음(ORA-04092)

실습 이행 소스의 trg_orders_bi는 BEFORE 행 트리거로 :NEW에 값을 넣어 주는 용도였음
MySQL 이행에서는 이 채번, 기본값 기능을 AUTO_INCREMENT와 DEFAULT로 대신했음

실습에서는 소스 DB 구성 예제에서 생긴 이력 중복 장애가 바로 이 AFTER 트리거 동작 때문이었다고 적었음(해당 예제는 데이터 이행 분야)

#개념과 동작 원리

이력 트리거 정의는 BEFORE와 AFTER 트리거에 있음

DML :OLD :NEW 실습 이력의 빈 칸
INSERT 없음(NULL) 새 값 old_sal
UPDATE 이전 값 새 값 없음
DELETE 지운 값 없음(NULL) new_sal

trg_orders_bi의 소스 본문은 수업 자료에 없고, 실습에서는 USER_SOURCE로 소스를 읽는 조회문만 실었음(객체 상태와 소스 조회)
그래서 이 트리거가 정확히 어떤 컬럼에 어떤 값을 넣었는지는 확인할 수 없음

#필수 명령어 또는 SQL

#이력 남기기

SQL*Plus (객체 소유 계정)데이터 또는 파일을 삭제함, 되돌릴 수 없음
EXEC p_raise_sal(7566, 10)                     -- 결과: JONES 2975 → 3273
INSERT INTO emp_t VALUES (7934, 'MILLER', 1300, 10);
DELETE FROM emp_t WHERE empno = 7934;
COMMIT;
SQL*Plus (객체 소유 계정)조회만 함
SELECT * FROM emp_t_audit;

결과 해석: UPDATE, INSERT, DELETE 이력 세 건이 남고, INSERT 행은 old_sal, DELETE 행은 new_sal이 비어 있음
INSERT ... VALUES에 값 네 개만 준 것은 실습 emp_t(emp_m 복사본)가 네 컬럼이라는 전제임
emp_m의 구조는 기재 없음
이 순서는 행 트리거와 문장 트리거의 삭제 차단 트리거를 만들기 전에 실행해야 DELETE가 성공함

#같은 트랜잭션 확인

SQL*Plus (객체 소유 계정)조회만 함
SELECT COUNT(*) FROM emp_t_audit;                   -- 결과: 3건
SQL*Plus (객체 소유 계정)객체 또는 설정을 변경함
UPDATE emp_t SET sal = sal + 100 WHERE deptno = 30; -- 결과: 2행, 이력 2건 추가
SQL*Plus (객체 소유 계정)조회만 함
SELECT COUNT(*) FROM emp_t_audit;                   -- 결과: 5건
SQL*Plus (객체 소유 계정)객체 또는 설정을 변경함
ROLLBACK;
SQL*Plus (객체 소유 계정)조회만 함
SELECT COUNT(*) FROM emp_t_audit;                   -- 결과: 다시 3건

결과 해석: 사용자 UPDATE를 롤백하자 트리거가 넣은 이력 두 건도 사라졌음
롤백과 무관하게 이력을 남기려면 별도 트랜잭션이 필요한데, 그 방법(자율 트랜잭션 등)은 실습 PL/SQL 페이지에 없음
자율 트랜잭션 예는 시퀀스와 채번 성능의 채번 함수에 있음

#이행 대상 트리거 소스 읽기

SQL*Plus (이행 소스 계정)조회만 함
SELECT line, text FROM user_source WHERE name = 'TRG_ORDERS_BI' ORDER BY line;

결과 해석: 개별 실행 출력은 기재 없음

SEO_HKabsumveritas@gmail.comBuilt with Claude Code & Codex

마지막 갱신 개인 학습 기록이며 운영 환경 적용 전 공식 문서 확인 필요

두 글자 이상 입력, 위아래 화살표로 이동하고 Enter로 열기