home
자바
home
🔫

14. 트리거(TRIGGER)

트리거 TRIGGER

내가 지정한 테이블에 INSERT, UPDATE, DELETE 등의 DML문에 의해 변경될 경우 (테이블에 이벤트가 발생했을 경우)
자동으로 매번 실행할 내용을 정의해둘 수 있는 객체
데이터 무결성을 보장
EX) 상황 1. 입출고에 대한 데이터가 기록(INSERT)될 때마다 해당 상품에 대한 재고수량 매번 수정(UPDATE)하겠다. 2. 회원탈퇴시 기존의 회원테이블에 데이터 DELETE 후 탈퇴된 회원들만 따로 보관하는 테이블에 자동 INSERT처리하겠다. 3. 신고횟수가 일정수를 넘었을 때 묵시적으로 블랙리스트 처리 되게끔 하겠다.
트리거 종류
1.
SQL문의 실행시기에 따른 분류
BEFORE TRIGGER : 내가 지정한 테이블에 이벤트가 발생되기 전에 트리거 실행
AFTER TRIGGER : 내가 지정한 테이블에 이벤트가 발생한 후에 트리거 실행
2.
SQL문에 의해 영향을 받는 각 행에 따른 분류
STATEMENT TRIGGER(문장트리거) : 이벤트가 발생한 SQL문에 대해 딱 한번만 트리거 실행
ROW TRIGGER(행트리거) : 해당 SQL문 실행할 때 마다 매번 트리거 실행 트리거 생성 구문 작성시 FOR EACH ROW옵션 기술해야됨
:OLD → BEFORE UPDATE(수정전 자료), BEFORE DELETE(삭제전 자료)
:NEW → AFTER INSERT(입력후 자료), AFTER UPDATE(수정후 자료)
트리거 생성 구문 [표현법] CREATE [OR REPLACE] TRIGGER 트리거명(TRG_) BEFORE|AFTER INSERT|UPDATE|DELETE ON 테이블명 [FOR EACH ROW] [DECLARE 변수선언;] BEGIN 실행내용; (해당 위에 지정된 이벤트 발생시 묵시적으로 자동으로 실행할 구문) [EXCEPTION 예외처리구문;] END; /

트리거 사용 전

상품 입고 및 출고 관련 예시
-- >> 필요한 테이블 및 시퀀스 생성 -- 1. 상품에 대한 데이터 보관할 테이블 (TB_PRODUCT) CREATE TABLE TB_PRODUCT( PCODE NUMBER PRIMARY KEY, -- 상품코드 PNAME VARCHAR2(30) NOT NULL, -- 상품명 BRAND VARCHAR2(30) NOT NULL, -- 브랜드명 PRICE NUMBER, -- 가격 STOCK NUMBER DEFAULT 0 -- 재고수량 ); -- 상품코드 중복안되게 매번 새로운 번호 발생시키는 시퀸스 (SEQ_PCODE) CREATE SEQUENCE SEQ_PCODE START WITH 200 INCREMENT BY 5; -- 샘플데이터 추가 INSERT INTO TB_PRODUCT VALUES(SEQ_PCODE.NEXTVAL, '갤럭시20', '샘송', 1400000, DEFAULT); INSERT INTO TB_PRODUCT VALUES(SEQ_PCODE.NEXTVAL, '아이폰12PRO', '사과', 1300000, 0); INSERT INTO TB_PRODUCT VALUES(SEQ_PCODE.NEXTVAL, '대륙폰', '샤우미', 600000, 20); COMMIT; -- 2. 상품 입출고 상세 이력 테이블 (TB_PRODETAIL) -- 어떤 상품이 어떤 날짜에 몇개가 입고 또는 출고가 되었는지 기록하는 테이블 CREATE TABLE TB_PRODETAIL( DCODE NUMBER PRIMARY KEY, -- 상세이력코드번호 PCODE NUMBER REFERENCES TB_PRODUCT, -- 상품코드 PDATE DATE NOT NULL, -- 상품입출고일 AMOUNT NUMBER NOT NULL, -- 입출고수량 STATUS CHAR(6) CHECK(STATUS IN ('입고', '출고')) -- 상태(입고/출고) ); -- 상세이력코드번호로 매번 새로운 번호 발생시켜서 들어갈 수 있게 도와주는 시퀀스 (SEQ_DCODE) CREATE SEQUENCE SEQ_DCODE;
SQL
복사
-- 200번 상품이 오늘날짜로 10개가 입고 INSERT INTO TB_PRODETAIL VALUES(SEQ_DCODE.NEXTVAL, 200, SYSDATE, 10, '입고'); -- 재고수량도 변경해야됨 UPDATE TB_PRODUCT SET STOCK = STOCK + 10 WHERE PCODE = 200; COMMIT; -- 205번 상품이 오늘날짜로 20개가 입고 INSERT INTO TB_PRODETAIL VALUES(SEQ_DCODE.NEXTVAL, 205, SYSDATE, 20, '입고'); UPDATE TB_PRODUCT SET STOCK = STOCK + 20 WHERE PCODE = 205; COMMIT; -- 200번 상품이 오늘날짜로 3개 출고 INSERT INTO TB_PRODETAIL VALUES(SEQ_DCODE.NEXTVAL, 200, SYSDATE, 3, '출고'); UPDATE TB_PRODUCT SET STOCK = STOCK - 3 WHERE PCODE = 200; COMMIT;
SQL
복사
입고, 출고시 재고수량을 일일이 변경해 주어야 함 → 실수가능성 有, 번거로움

트리거 사용 후

-- TB_PRODETAIL 테이블에 INSERT 이벤트 발생시 -- TB_PRODUCT 테이블에 매번 자동으로 재고 수량 UPDATE 되게끔 트리거 정의 CREATE OR REPLACE TRIGGER TRG_02 AFTER INSERT ON TB_PRODETAIL FOR EACH ROW BEGIN -- 상품이 입고된 경우 => 재고수량 증가 IF (:NEW.STATUS = '입고') THEN UPDATE TB_PRODUCT SET STOCK = STOCK + :NEW.AMOUNT WHERE PCODE = :NEW.PCODE; END IF; -- 상품이 출고된 경우 => 재고수량 감소 IF (:NEW.STATUS = '출고') THEN UPDATE TB_PRODUCT SET STOCK = STOCK - :NEW.AMOUNT WHERE PCODE = :NEW.PCODE; END IF; END; / -- 210번 상품이 오늘날짜로 9개 출고 INSERT INTO TB_PRODETAIL VALUES(SEQ_DCODE.NEXTVAL, 210, SYSDATE, 9, '출고'); -- 205번 상품이 오늘날짜로 100개가 입고 INSERT INTO TB_PRODETAIL VALUES(SEQ_DCODE.NEXTVAL, 205, SYSDATE, 100, '입고');
SQL
복사