바닥코딩
트리거 본문
트리거는 다른 저장 서브프로그램들처럼 고유한 이름을 가지고, 데이터베이스에 저장되며 반복적으로 호출되는 서브프로그램입니다. 하지만 다른 서브프로그램들과는 차이점을 가지고 있는데, 그건바로 트리거는 프로그램에서 직접 호출되어 사용할 수 없습니다. 그렇다면 트리거를 어떻게 실행할까? 에 대한 의문이 생길 수도 있는데, 트리거는 데이터베이스에서 특정 이벤트가 발생할 때마다 데이터베이스에 의해 자동으로 호출됩니다.
예제를 통해 트리거를 생성을 살펴보겠습니다.
create or replace trigger tr_emp_ins_upd_validate
before insert or update of sal, comm on emp -- 발생시점
referencing old as old new as new -- 참조절
for each row
begin
if inserting then
if : new.sal <0
DBMS_OUTPUT.PUT_LINE('급여에는 음수가 올 수 없습니다,');
:new.sal := null;
end if;
if : new.comm <0 then
dbms_output.put_line('커미션이 음수입니다.');
:new.comm :=null;
end if;
elsif updating then
if :old.sal > : new.sql then
DBMS_OUTPUT.PUT_LINE('급여가 낮아졌씁니다');
:new.sal := old.sal;
end if;
if : old.comm > : new.comm then
DBMS_OUTPUT.PUT_LINE('커미션이 낮아졌습니다');
:new.comm := old.comm;
end if;
end IF;
end;
하나의 트리거의 예시입니다. 이 구문에서 before insert는 직역한 뜻과 같이 insert 되기 전을 뜻합니다. 이것을 발생시점이라고 하는데 해당 트리거는 insert쿼리가 발생하기전 아래 로직을 수행하기 되는 것입니다.
트리거는 다양한 용도로 사용되는데, 대표적인 사용 예는 아래와 같습니다.
- 한테이블이 변경될 때 동시에 다른 테이블도 변경이 되어야 하는경우
- 데이터의 변경이 DB에 저장되기 전에 값을 검증하고 필요시 다른 값으로 변경
- 조건 판단에 따라서 이벤트의 발생을 허용하거나 차단
- 발생한 이벤트 로그 쌓을 때
- 자동으로 계산 칼럼의 값 생성
- VIEW에 대한 DML문장 수행 시 다른 테이블을 변경하고 싶은 경우
- 계약 조건으로 생성할 수 없는 복잡한 업무규칙을 적용하여 데이터의 무결성 보장
- 분산 데이터베이스 환경에서 부모 테이블과 자식 테이블 간 참조 무결성 보장
트리거의 발생시점
앞선 예제의 before insert와 같이 DML에서 트리거의 발생시점을 정의할 수 있으며, 종류로는 3가지가 있습니다.
- before : 해당 이벤트 발생 전
- after: 해당 이벤트 발생 후
- instead of : 해당 이벤트 대신~
위와 같이 발생 시점에 따라서 분류가 가능뿐만 아니라 DML 이벤트는 서로 결합하여 사용이 기능합니다. INSERT OR UDDATE(insert문 이거나 또는 UPDATE 문일 때도) 이런식의 결합을 하면 더 유연한 상황을 설정하는 것이 가능합니다.
CREATE OR REPLACE TRIGGER TR_EXAM
BEFORE INSERT ON EMP -- INSERT 발생 선
AFTER INSERT ON EMP -- INSERT 발생 후
INSTEAD OF INSERT ON EMP -- INSERT 대신 수행
INSERT OR DELETE OR UPDATE ON EMP -- INSERT, UPEDATE, DELETE 모두 수행
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
BEGIN
/*
트리거 내용
*/
end;