1. 트리거(Trigger)의 개요
◎ 트리거란?
▷ 사전적 의미로 ‘방아쇠’
▷ 방아쇠 당기면 ‘자동’으로 총알이 나가듯이 테이블에 무슨 일이 일어나면 ‘자동’으로 실행
▷ 제약 조건과 더불어 데이터 무결성을 위해 MySQL에서 사용할 수 있는 기능
▷ 테이블에 DML문(Insert, Update, Delete 등) 이벤트가 발생될 때 작동
▷ 테이블에 부착되는 프로그램 코드
▷ 직접 실행 불가
▶ 테이블에 이벤트 일어나야 자동 실행
▷ IN, OUT 매개 변수를 사용할 수 없음
▷ MySQL은 View에 트리거 부착 불가
1. 테이블 생성
-- 트리거 : 테이블에 DML(i, u, d)문이 실행 될때 자동으로 SQL문을 실행 create database if not exists testDB; use testdb; create table if not exists testTbl (id int, txt varchar(10)); insert into testTbl values(1, '레드벨벳'); insert into testTbl values(2, '잇지'); insert into testTbl values(3, '블랙핑크'); select * from testtbl;
2. 트리거 생성 및 출력
drop trigger if exists testTrg; -- 트리거 부착 delimiter // create trigger testTrg -- 트리거를 하나 생성 after delete -- delete를 실행하고 난 뒤 트리거 작동 on testTbl -- testTbl에 트리거를 부착 for each row -- 한 행씩 실행이 되게 설정 begin set @msg = '가수 그룹이 삭제됨'; -- 트리거가 일어났을때 실행할 구문 end // delimiter ; -- 데이터를 삽입, 수정, 삭제 set @msg = ' '; insert into testTbl values(4,'마마무'); -- 삽입시 아무일도 일어나지 않는다. select @msg; set SQL_SAFE_UPDATES = 0; update testTbl set txt = '블핑' where ID = 3; -- 데이터 수정시 아무일이 일어나지 않는다. select @msg; delete from testTbl where id=4; -- 데이터 삭제시 트리거 작업이 일어나게 된다. select @msg; -- '가수 그룹이 삭제됨' 반환
2. 트리거의 종류
◎ AFTER 트리거
▷ 테이블에 INSERT, UPDATE, DELETE 등의 작업이 일어났을 때 작동
▷ 이름이 뜻하는 것처럼 해당 작업 후에(After) 작동
◎ BEFORE 트리거
▷ BEFORE 트리거는 이벤트가 발생하기 전에 작동
▷ INSERT, UPDATE, DELETE 세 가지 이벤트로 작동
3. 트리거의 사용
◎ 트리거 문법
◎ AFTER 트리거의 사용
▷ 예제 요구 사항
1. 회원 테이블에 update나 delete를 시도하면 수정 또는 삭제된 데이터를 별도의 테이블에 보관하고 변경된 일자와 변경한 사람을 기록
▷ insert나 update 작업이 일어나는 경우, 변경되기 전의 데이터를 저장할 테이블 생성
-- AFTER 트리거 사용 -- 회원 테이블에 update, delete를 시도하면 수정 또는 삭제된 데이터를 -- 별도의 테이블에 보관하고 변경된 일자와 변경한 사람을 기록 use sqldb; drop table buytbl; drop table backup_usertbl; create table backup_usertbl ( userID char(8) not null primary key, name varchar(10) not null, birthYear int not null, addr char(2) not null, mobile1 char(3), mobile2 char(8), height smallint, mDate date, modType char(2), -- 변경된 타입 : 수정 또는 삭제 modDate date, -- 변경된 날짜 modUser varchar(256) -- 변경한 사용자 );
2. 변경(Update) 발생시 작동하는 backUserTbl_UpdateTrg 트리거 생성
-- 변경(update)이 발생할 때 작동하는 트리거 drop trigger if exists backUserTbl_UpdateTrg; delimiter // create trigger backUserTbl_UpdateTrg after update -- 업데이트 이후에 동작 on usertbl -- 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 ;
3. 삭제(Delete) 발생시 작동하는 backUserTbl_DeleteTrg 트리거 생성
-- 삭제(delete)가 발생할 때 작동하는 트리거 drop trigger if exists backUserTbl_DeleteTrg; delimiter // create trigger backUserTbl_DeleteTrg after delete -- 삭제 이후에 동작 on usertbl -- 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 ;
4. 데이터 업데이트 및 삭제
set SQL_SAFE_UPDATES = 0; update usertbl set addr = '몽고' where userID = 'JKW'; delete from usertbl where height >= 177;
5. 수정 또는 삭제된 내용이 잘 보관되어 있는지 결과 확인
select * from backup_userTbl;
◎ insert 트리거 예제
-- insert 트리거 drop trigger if exists usertbl_insertTrg; 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', '11111111', 181, '2019-12-25');
'데이터의 입력을 시도했습니다. 귀하의 정보가 서버에 기록되었습니다.'를 반환
◎ 트리거가 생성하는 임시 테이블
▷ INSERT, UPDATE, DELETE 작업이 수행되면 임시 사용하는 시스템 테이블
▷ 이름은 ‘NEW’와 ‘OLD’
◎ BEFORE 트리거의 사용
▷ 테이블에 변경이 가해지기 전 작동
▷ BEFORE 트리거 활용 예
▶ BEFORE INSERT 트리거를 부착해 놓으면 입력될 데이터 값을 미리 확인해서 문제가 있을 경우에
다른 값으로 변경
▷ BEFORE 트리거 실습
▶ 값이 입력될 때, 출생년도의 데이터를 검사해서 데이터에 문제가 있으면 값을 변경시켜서 입력시키는
BEFORE INSERT 트리거 작성
1. 트리거 생성
-- BEFORE 트리거 : 트리거 실행 이전에 SQL 실행 - 입력되는 데이터의 문제가 있는지 확인해서 수정 -- 1900년 이전의 데이터가 입력되면 0으로 표기, 현재년도보다 더 높은 년도 입력되면 현재년도로 수정 -- sqldb.sql을 실행해서 sql 초기화 use sqldb; drop trigger if exists usertbl_BeforeInsertTrg; 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 ;
2. 값 입력 ( 두 값 모두 출생년도에 문제 있음)insert into userTbl values('AAA', '에이', 1877, '서울', '011', '1112222', 181, '2022-12-25'); insert into userTbl values('BBB', '비이', 2977, '경기', '011', '1113333', 171, '2019-3-25');
3. SELECT * FROM userTbl문으로 확인
4. SHOW TRIGGERS문으로 데이터베이스에 생성된 트리거 확인show triggers from sqldb;
5. 트리거 삭제
drop trigger usertbl_BeforeInsertTrg;
3. 기타 트리거에 관한 내용
◎ 다중 트리거 (Multiple Triggers)
▷하나의 테이블에 동일한 트리거가 여러 개 부착되어 있는 것
▶ ex) AFTER INSERT 트리거 한 개 테이블에 2개 이상 부착
◎ 중첩 트리거 (Nested Triggers)
▷트리거가 또 다른 트리거를 작동시키는 것
◎ 중첩 트리거 예시
1. 테이블 생성
-- 중첩 트리거 drop database if exists triggerdb; 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 ); insert into prodTbl values('사과', 100); insert into prodTbl values('배', 100); insert into prodTbl values('귤', 100); select * from prodTbl;
2. 구매 테이블에서 구매가 있을 때 테이블 개수 감소
-- 중첩 트리거 -- 구매 테이블에서 구매가 있을 때(insert) 물품 테이블에 개수를 감소 drop trigger if exists orderTrg; delimiter // create trigger orderTrg -- 구매 트리거 after insert -- orderTbl에 insert : 구매자가 물품 구매가 있을 때 on orderTbl for each row begin update prodTbl set account = account - new.orderamount where prodName = new.prodName; -- 제품 테이블의 재고수량을 주문수량 제외하고 재고수량 수정 end // delimiter ;
3. 배송 테이블에 새 배송 건을 입력하는 트리거-- 배송 테이블에 새 배송 건을 입력하는 트리거 drop trigger if exists prodTrg; delimiter // create trigger prodTrg -- 물품 트리거 after update on prodTbl for each row begin declare orderAmount int; -- 주문 개수 : (변경 전의 개수 - 변경 후의 개수) set orderAmount = old.account - new.account; insert into deliverTbl(prodName, account) values(new.prodName, orderAmount); end // delimiter ; select * from ordertbl; select * from prodtbl; select * from delivertbl;
◎ 트리거의 작동 순서
▷ 하나의 테이블에 여러 개의 트리거가 부착된 경우 트리거의 작동 순서 지정 가능
트리거는 테이블에 부착해서 사용해야합니다.
변경, 삭제, 삽입 등의 변동사항이 있을 때 따로 이력을 남길 수 있고 무작위로 변경하지 못하게 할 때 사용하면 좋을 것 같아요!!!
많은 분들의 피드백은 언제나 환영합니다! 많은 댓글 부탁드려요~~
'BackEnd > DB(SQL)' 카테고리의 다른 글
[DB_MySQL] 이것이 MySQL이다 ch11 전체 텍스트 검색과 파티션 2 (파티션) (0) | 2023.02.13 |
---|---|
[DB_MySQL] 이것이 MySQL이다 ch11 전체 텍스트 검색과 파티션 1 (전체 텍스트 검색) (0) | 2023.02.13 |
[DB_MySQL] 이것이 MySQL이다 ch10 스토어드 프로그램 3(커서) (0) | 2023.02.12 |
[DB_MySQL] 이것이 MySQL이다 ch10 스토어드 프로그램 2(스토어드 함수) (0) | 2023.02.11 |
[DB_MySQL] 이것이 MySQL이다 ch10 스토어드 프로그램 1(스토어드 프로시저, Stored Procedure) (0) | 2023.02.10 |