1. 트리거란?
트리거(trigger)란 데이터의 변경(INSERT, DELETE, UPDATE)문이 실행될 때 자동으로 실행되는 프로시저를 말한다. 트리거를 설정해 놓으면 데이터가 변경되기 전(BEFORE)과 후(AFTER) 시점에 개입하여 원하는 로직을 실행할 수 있다. 트리거가 프로시저와 다른 점은 프로시저는 호출을 해야지 실행이 된다면 트리거는 조건이 충족되면 자동으로 실행된다는 것이다. 코드로 살펴보는 것이 이해가 빠를 것이다.
2. 트리거 기본 문법
CREATE [OR REPLACE] Trigger 트리거명
Before (or After)
UPDATE OR DELETE OR INSERT ON 테이블명 --Trigger_event
[FOR EACH ROW]
DECLARE
--변수선언부
BEGIN
--프로그램 코딩부
END;
2.1 BEFORE,AFTER
트리거만의 특이한 점은 시점을 선택할 수 있다는 점이다. 트리거가 발동하는 조건은 INSERT 혹은 UPDATE, DELETE 이벤트가 발생할 때 이다. 즉, UPDATE, DELETE, INSERT SQL문이 실행될 때 트리거가 작동한다는 것이다. 트리거는 이벤트가 발생하고나서 개발자가 정의해 놓은 코드를 실행하기 때문에 시점이 중요하다. SQL로 요청된 내용이 실행되기 전에 코드를 실행하고 싶다면 BEFORE을 선언하고 SQL문이 실행된 이후 데이터에 접근하고 싶다면 AFTER를 사용한다.
2.2 Trigger_event ON 테이블명
어떤 이벤트가 발생할 때 트리거를 작동시킬 지 선택할 수 있다. 예를들어 INSERT문이 실행될 때 트리거를 실행하고 싶다면 Trigger_event에 INSERT를 선언하면 된다. 아래 구문은 dept테이블에 대해 INSERT문이 실행된 후(AFTER)에 작동되는 insert_trigger라는 이름을 가진 트리거 일부분이다. 만약 INSERT뿐만 아니라 다른 이벤트도 추가하고 싶다면 OR DELETE 등으로 선언할 수 있다.
CREATE OR REPLACE trigger insert_trigger
after
INSERT ON dept
2.3 FOR EACH ROW
FOR EACH ROW는 선언할 수도 있고 생략할 수도 있다. 만약 선언된다면 매 행에 대해서 트리거가 실행된다. 트리거가 발동될 때 한 번 작동하느냐 혹은 트리거가 매 행에 대해서 반복적으로 작동하느냐 차이라고 보면 된다.
3. 트리거 예제
트리거의 사용법을 살펴보기 위해 이벤트가 발생할 때 복사된 테이블에도 똑같이 이벤트를 적용하는 트리거를 한번 작성해보겠다.
3.1 테이블 복사
기존에 있던 dept라는 테이블을 아래 명령어를 통해 복사한다. dept에 들어있는 값은 아래사진과 같다. 이제 dept_copy라는 테이블이 생겼다.
CREATE table dept_copy as
SELECT * FROM dept;
3.2 트리거 작성
dept 테이블에 값이 수정, 삭제, 입력 될 때 마다 변경된 내용을 dept_copy에도 똑같이 적용하는 트리거를 작성해보았다. 위에서 살펴본 문법만 숙지하면 쉽게 이해할 수 있을 것이다. BEGIN과 END사이에 실행하고자 하는 코드를 작성하게 되는데 이때 IF문의 조건으로 inserting, updating, deleting이 사용된 것을 볼 수 있다. 이는 각각의 이벤트가 발생할 때를 의미하는 예약어로 inserting이라는 조건은 "insert문이 실행되면" 이라는 의미를 갖는다.
CREATE OR REPLACE trigger trg_deptcopy
after
INSERT OR DELETE OR UPDATE ON dept
FOR EACH ROW
BEGIN
IF inserting THEN
INSERT INTO dept_copy(deptno, dname, loc)
VALUES(:new.deptno, :new.dname, :new.loc);
ELSIF updating THEN
UPDATE dept_copy
SET dname = :new.dname, loc = :new.loc
WHERE deptno = :old.deptno;
ELSIF deleting THEN
DELETE FROM dept_copy
WHERE deptno = :old.deptno;
END IF;
END;
컬럼의 이름 앞에 :new, :old라는 문법이 사용되는데 이는 이벤트로 인해 변경되기 전의 컬럼값과 이후의 컬럼값을 각각 접근하기 위해 사용되는 문법이다. 위 트리거를 저장한 후에 dept테이블에 자료를 추가하면 dept_copy테이블에도 같은 값이 추가되는 것을 볼 수 있다.
4. 트리거 사용처
위에서도 잠깐 언급한 것 처럼 트리거는 이벤트가 발생할 때 자동으로 실행되는 프로시져이다. 자동으로 실행된다는 것은 개발자가 작성해야 하는 코드가 줄어든다는 의미가 된다. 위에서 살펴본 데이터 복사 트리거도 원래라면 일일히 복사테이블에 값을 복사해줘야 한다. 하지만 트리거를 작성해 놓음으로 인해 데이터 입력시점에 따른 원본데이터와 복사데이터 간 데이터 일관성문제도 해결할 수 있다.