[Oracle PL/SQL] 트리거(Trigger)

코린이·2024년 9월 20일

ORACLE PL/SQL

목록 보기
6/7

트리거(Trigger)

트리거는 특정 이벤트가 발생할 때 자동으로 실행되는 일종의 저장 프로시저이다.

주로 데이터베이스의 무결성을 유지하거나 특정 작업(log기록)을 자동화하기 위해 사용되며, 데이터베이스 테이블의 특정 변화(삽입, 수정, 삭제)에 따라 동작된다.

또한, DDL 언어를 사용하는 데 있어 삭제(DROP, TRUNCATE) 실행을 막을 수 있다.
(사용자 에러를 발생시킴으로서 DB의 다양한 객체의 삭제를 막을 수 있다.)

✅ 트리거(Trigger) 구조

트리거를 정의할 때는 사용 목적에 따라 다양하게 정의할 수 있다.

타이밍

트리거는 실행 타이밍에 따라 정할 수 있다.
BEFORE : 이벤트가 발생하기 전에 실행
AFTER : 이벤트가 발생한 후에 실행

트리거 실행 Level

트리거는 하나의 SQL문에 대해 한 번만 실행 할 것인지, 하나의 SQL문에서 실행되는 각각의 행에 대해 실행 할 것인지를 정할 수 있다.
ROW LEVEL : 각 행에 대해 트리거가 실행
STATEMENT LEVEL : 트리거가 실행된 SQL 문에 대해 한 번만 실행

NEW/ORD

트리거에는 NEW/ORD를 사용하여 변경하는 값과 변경되기 전 값을 구분할 수 있다.
NEW : INSTER: 신규 값 입력, UPDATE: 값 수정
ORD : UPDATE: 수정 전 값, DELETE: 삭제할 값


CREATE OR REPLACE NONEDITIONABLE TRIGGER <트리거명>
    BEFORE    --AFTER 또는 BEFORE 작성
    DELETE OR INSERT OR UPDATE  --DELETE, INSERT, UPDATE에 대해서 트리거 실행
    ON <테이블명>
    FOR EACH ROW  --각 행에 대해 트리거가 실행 (해당 쿼리문 생략시 STATEMENT으로 동작)
   
DECLARE

BEGIN
    IF INSERTING THEN
		--INSERT 실행 시 동작
    ELSIF UPDATING THEN
		--UPDATE 실행 시 동작
    ELSIF DELETING THEN
    	--DELETE 실행 시 동작
    END IF;

    -- 트리거가 발생하면 자동으로 LOG 테이블에 기록 저장
    INSERT INTO <LOG 테이블> 
    (...)
    values
    (...);

END;

✅ 트리거 조건

트리거를 정의할 때 특정 속성의 속성값을 지정하여, 해당 속성값일 때만 트리거를 작동할 수 있다.

-- 예시
WHEN (NEW.CUSTOMER_CLASS = 'VIP')  --고객 등급이 VIP일 때만 트리거 작동
CREATE OR REPLACE NONEDITIONABLE TRIGGER <트리거명>
    BEFORE    --AFTER 또는 BEFORE 작성
    DELETE OR INSERT OR UPDATE  --DELETE, INSERT, UPDATE에 대해서 트리거 실행
    ON <테이블명>
    FOR EACH ROW  --각 행에 대해 트리거가 실행 (해당 쿼리문 생략시 STATEMENT으로 동작)
    WHEN (NEW.<테이블 속성명> = '속성값')  --특정 속성 값에 대해서만 동작하고 싶을때

트리거에서 UPDATE 이벤트를 수행할 때는 속성에 대한 조건을 기입할 수 있다.
UPDATE 작성 후 OF <속성명>을 작성하여 해당 속성에만 트리거가 동작하게 할 수 있다.

DELETE OR INSERT OR UPDATE OF <속성명>

✅ 시스템 트리거(DDL)

트리거가 스키마나 데이터베이스에서 생성되는 경우 트리거 이벤트는 DDL이나 데이터베이스 작업 문으로 구성되며 해당 트리거를 시스템 트리거(system trigger) 라고 합니다 .

CREATE OR REPLACE NONEDITIONABLE TRIGGER <트리거명>
BEFORE 
DROP ON <스키마명>.<유형(TABLE, VIEW, SCHEMA, DATABASE 중 하나)>

BEGIN
   
    IF ORA_DICT_OBJ_TYPE = '<객체 타입>' THEN
		RAISE_APPLICATION_ERROR(<사용자 에러 코드>, '<사용자 에러명>');
    END IF;
END;

만약 특정 스키마 트리거에 아래와 같은 코드가 있으면, 테이블을 삭제할 수 없다.

IF ORA_DICT_OBJ_TYPE = 'TABLE' THEN
	RAISE_APPLICATION_ERROR(-20000, '해탕 테이블에 대한 권한 없음');
END IF;

객체 타입이 아닌 객체명에 따라 트리거 이벤트를 작동하게 하려면, ORA_DICT_OBJ_NAME을 사용하면 된다.

0개의 댓글