✍️ Study Note
트리거 (Trigger)
- 테이블에 삽입, 수정, 삭제 등의 작업(이벤트) 발생 시, 자동으로 작동하는 개체.
- 데이터 무결성에 도움
- 직접 실행시키지 못하고, 테이블에 이벤트가 발생할 때 자동으로 실행
AFTER 트리거 생성
DELIMITER // -- 트리거 생성
CREATE TRIGGER TESTTRG -- 트리거 작동조건
AFTER DELETE
ON TESTTBL22 -- TESTTBL22 테이블에 이벤트 발생 시
FOR EACH ROW
BEGIN
SET @MSG = '가수 그룹이 삭제됨'; -- 트리거로 발생하는 작업
END //
DELIMITER ;
SET @MSG = '';
INSERT INTO TESTTBL22 VALUES(4,'마마무'); -- 트리거 X
SELECT @MSG;
UPDATE TESTTBL22 SET TXT = '블핑' WHERE ID =3; -- 트리거 X
SELECT @MSG;
DELETE FROM TESTTBL22 WHERE ID =4; -- 트리거 O
SELECT @MSG;
1. UPDATE / DELETE + AFTER TRIGGER 예시
DELIMITER //
CREATE TRIGGER BACKUPUSERTBL_UPDATETRG
AFTER UPDATE -- 수정 시 트리거 작동
ON USERTBL
FOR EACH ROW
BEGIN
INSERT INTO BACKUP_USERTBL VALUES
(OLD.USERID, OLD.NAME, OLD.BIRTHYEAR, OLD.ADDR, OLD.MOBILE1,
OLD.MOBILE2, OLD.HEIGHT, OLD.MDATE, '수정', CURDATE(), CURRENT_USER());
END//
DELIMITER ;
DELIMITER //
CREATE TRIGGER BACKUSERTBL_DELTETRG
AFTER DELETE -- 삭제 시 트리거 작동
ON USERTBL
FOR EACH ROW
BEGIN
INSERT INTO BACKUP_USERTBL VALUES
(OLD.USERID, OLD.NAME, OLD.BIRTHYEAR, OLD.ADDR, OLD.MOBILE1,
OLD.MOBILE2, OLD.HEIGHT, OLD.MDATE, '삭제', CURDATE(), CURRENT_USER());
END //
DELIMITER ;
UPDATE USERTBL SET ADDR = '몽고' WHERE USERID = 'JKW';
DELETE FROM USERTBL WHERE HEIGHT >=177;
SELECT * FROM BACKUP_USERTBL; -- 트리거 작동됨
TRUNCATE TABLE USERTBL;
SELECT * FROM BACKUP_USERTBL; -- 트리거 작동안됨. DELETE문이 아니기에
TRUNCATE는 DELETE TRIGGER 작동시키지 않음.
2. INSERT + AFTER TRIGGER 예시
DELIMITER //
CREATE TRIGGER USERTBL_INSERTTRG
AFTER INSERT
ON USERTBL
FOR EACH ROW
BEGIN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = "데이터의 입력을 시도했습니다. 귀하의 정보가 서버에 입력되었습니다.";
END//
DELIMITER ;
INSERT INTO USERTBL VALUES('ABC', '에비씨', 1977, '서울', '011', '1111111', 181, '2019-12-25', 'A');
BEFORE 트리거 생성
DELIMITER //
CREATE TRIGGER USERTBL_BEFOREINSERTTRG
BEFORE INSERT
ON USERTBL
FOR EACH ROW
BEGIN
IF NEW.BIRTHYEAR < 1900 THEN
SET NEW.BIRTHYEAR = 0;
ELSEIF NEW.BIRTHYEAR > YEAR(CURDATE()) THEN
SET NEW.BIRTHYEAR = YEAR(CURDATE());
END IF;
END//
DELIMITER ;
INSERT INTO USERTBL VALUES -- 데이터 삽입
('AAA', '에이', 1877, '서울', '011', '1112222', 181, '2022-12-25','B'),
('BBB', '비이', 2977, '경기', '011', '1113333', 171, '2019-03-25','A');
SELECT * FROM USERTBL; -- 1번은 0, 2번은 현재년도 입력된것을 확인할 수 있음
트리거가 생성하는 임시 테이블
NEW
- INSERT, UPDATE 작업 시, 변경할 새로운 데이터를 잠시 저장하는 테이블.
- NEW에 저장되었다가 '작업 테이블'에 값이 입력, 변경된다
OLD
- DELETE, UPDATE 작업 시, 삭제 또는 변경되기 전의 예전 값이 저장되는 테이블
트리거 조회, 삭제
SHOW TRIGGERS FROM SQLDB;
DROP TRIGGER USERTBL_INSERTTRG;
기타 트리거
- 다중 트리거 : 하나의 테이블에 동일한 트리거 여러 개 부착
- 중첩 트리거 : 트리거가 또 다른 트리거를 작동하는 것
중첩트리거 예시
제품 주문이 들어오면 (ORDERTBL), 제품 수가 줄어들고 (PRODTBL) 배송 내역이 저장되도록 (DELIVERTBL)
-- 준비#1 테이블 생성
CREATE DATABASE IF NOT EXISTS TRIGGERDB;
USE TRIGGERDB;
CREATE TABLE ORDERTBL
(ORDERNO INT AUTO_INCREMENT PRIMARY KEY, USERID VARCHAR(5), PRODNAME VARCHAR(5), ORDERAMOUNT INT);
CREATE TABLE PRODTBL
(PRODNAME VARCHAR(5), ACCOUNT INT);
CREATE TABLE DELIVERTBL
(DELIVERNO INT AUTO_INCREMENT PRIMARY KEY, PRODNAME VARCHAR(5), ACCOUNT INT);
-- 준비#2 데이터 입력
INSERT INTO PRODTBL VALUES ('사과', 100), ('귤', 100), ('배', 100);
-- 트리거(ORDER -> PROD) 생성
DELIMITER //
CREATE TRIGGER ORDERTRG
AFTER INSERT
ON ORDERTBL -- ORDERTBL에 주문이 들어올 경우
FOR EACH ROW
BEGIN
UPDATE PRODTBL SET ACCOUNT = ACCOUNT - NEW.ORDERAMOUNT -- PRODTBL의 상품개수가 줄어든다
WHERE PRODNAME = NEW.PRODNAME;
END //
DEILMITER ;
-- 트리거(PROD -> DELIVER) 생성
DELIMITER //
CREATE TRIGGER PRODTRG
AFTER UPDATE
ON PRODTBL -- PRODTBL에 업데이트가 있을 경우
FOR EACH ROW
BEGIN
DECLARE ORDERAMOUNT INT;
SET ORDERAMOUNT = OLD.ACCOUNT - NEW.ACCOUNT; -- PRODTBL의 OLD, NEW 값 이용해서 주문수량 확인
INSERT INTO DELIVERTBL (PRODNAME, ACCOUNT)
VALUES(NEW.PRODNAME, ORDERAMOUNT); -- DELIVERTBL에 새로운 수량 업데이트
END//
DELIMITER ;
-- 테스트 (데이터입력)
INSERT INTO ORDERTBL VALUES (NULL, 'JOHN', '배', 5);
SELECT * FROM ORDERTBL;
SELECT * FROM PRODTBL;
SELECT * FROM DELIVERTBL;
'코딩공부' 카테고리의 다른 글
[SQL] MYSQL 스토어드 함수 (0) | 2021.11.08 |
---|---|
[SQL] MYSQL 스토어드 프로시저 (0) | 2021.11.07 |
[SQL] MySQL 테이블 압축, 임시테이블 (0) | 2021.10.23 |
[Power BI] MySQL server - Power BI 연결하기 (1) | 2021.10.22 |
[SQL] MYSQL 테이블스페이스 설정, 쿼리 응답시간 에러 해결방법 (0) | 2021.10.21 |