개발/MySQL
[혼자공부하는SQL] 20강
pangil_kim
2025. 3. 1. 07:34
728x90
07-3 자동으로 실행되는 트리커
0. 시작하기 전에
- 트리거는 자동으로 수행하여 사용자가 추가 작업을 잊어버리는 실수를 방지해준다.
- INSERT, UPDATE, DELETE가 실행되면, 방아쇠가 당겨져서 트리거를 자동으로 작동한다.
- ex) 직원 테이블에서 사원을 삭제하면, 해당 데이터를 자동으로 퇴사자 테이블에 들어가도록 설정할 수 잇다. 즉, 트리거를 사용하면 데이터에 오류가 발생하는 것을 막을 수 있고, 이런 것을 데이터 무결성이라고 부르기도 한다.
1. 트리거의 기본
1) 트리거의 개요
- 트리거란? 테이블에 INSERT나 UPDATE 또는 DELETE 작업이 발생하면 실행되는 코드이다.
- ex) 해당 데이터가 삭제 되기 전에 다른 곳으로 자동으로 저장해주는 기능이 있다면, 사용자는 더 이상 행 데이터를 삭제하기 전에 다른 곳에 저장해야 하는 부담에서 벗어나게 될 뿐 아니라, 모든 것이 자동으로 처리되므로 삭제된 모든 사용자 정보는 완벽하게 별도의 장소에 저장될 것이다.
2) 트리거의 기본 작동
(1) 설명
트리거는 테이블에서 DML(Data Manipulation Language)문인 INSERT, UPDATE, DELETE 등의 이벤트가 발생될 때 작동한다.
- 테이블에 미리 부착(attach)되는 프로그램 코드라고 생각하면 된다.
- 이 책에서 언급하는 트리거는 AFTER트리커이다. BEFORE 트리거는 작동 방식이 조금 다르다.
(2) 특징
- 트리거는 스토어드 프로시저와 문법이 비슷하지만, CALL 문으로 직접 실행시킬 수는 없고, 오직 테이블에 INSERT, UPDATE, DELETE 등의 이벤트가 발생할 경우에만 자동으로 실행된다.
- 또한, 스토어드 프로시저와 달린 트리거에는 IN, OUT 매개변수를 사용할 수 없다.
(3) 예시
-- 기본 세팅
CREATE TABLE IF NOT EXISTS trigger_table (id INT, txt VARCHAR(10));
INSERT INTO trigger_table VALUES(1, '레드벨벳');
INSERT INTO trigger_table VALUES(2, '잇지');
INSERT INTO trigger_table VALUES(3, '블랙핑크');
-- 트리거 생성
DROP TRIGGER IF EXISTS myTrigger;
DELIMITER $$
CREATE TRIGGER myTrigger -- 트리거 이름
AFTER DELETE -- 삭제후에 작동하도록 지정
ON trigger_table -- 트리거를 부착할 테이블
FOR EACH ROW -- 각 행마다 적용시킴
BEGIN
SET @msg = '가수 그룹이 삭제됨' ; -- 트리거 실행시 작동되는 코드들
END $$
DELIMITER ;
SET @msg = '';
-- 트리거 발생 : X (INSERT, UPDATE)
INSERT INTO trigger_table VALUES(4, '마마무');
SELECT @msg;
UPDATE trigger_table SET txt = '블핑' WHERE id = 3;
SELECT @msg;
-- 트리거 발생 : O (DELETE)
DELETE FROM trigger_table WHERE id = 4;
SELECT @msg;
2. 트리거 활용
0) 상황
- 은행의 창구에서 새로 계좌를 만들 때 INSERT를 사용한다.
- 계좌에 입금하거나 출금하면 UPDATE를 사용해서 값을 변경하며, 계좌를 폐기하면 DELETE가 작동한다.
- 그런데 계좌라는 중요한 정보를 누가 입력/수정/삭제했는지 알 수 없다면, 나중에 계좌에 문제가 발생했을 때 원인을 파악할 수 없을 것이다.
- 이럴 때를 대비해서 데이터에 입력/수정/삭제가 발생할 때, 트리거를 자동으로 작동시켜, 데이터를 변경한 사용자의 시간 등을 기록할 수 있다.
→ 고객 테이블에 입력된 회원의 정보가 변경될 때, 변경한 사용자, 시간, 변경 전의 데이터 등을 기록하는 트리거를 만들어 보자.
1) 코드
(1) 기본 세팅
USE market_db;
CREATE TABLE singer (SELECT mem_id, mem_name, mem_number, addr FROM member);
DROP TABLE IF EXISTS backup_singer;
CREATE TABLE backup_singer
( mem_id CHAR(8) NOT NULL ,
mem_name VARCHAR(10) NOT NULL,
mem_number INT NOT NULL,
addr CHAR(2) NOT NULL,
modType CHAR(2), -- 변경된 타입. '수정' 또는 '삭제'
modDate DATE, -- 변경된 날짜
modUser VARCHAR(30) -- 변경한 사용자
);
(2) 트리거 생성
-- UPDATE 변경 후 작동하는 트리거
DROP TRIGGER IF EXISTS singer_updateTrg;
DELIMITER $$
CREATE TRIGGER singer_updateTrg -- 트리거 이름
AFTER UPDATE -- 변경 후에 작동하도록 지정
ON singer -- 트리거를 부착할 테이블
FOR EACH ROW
BEGIN
INSERT INTO backup_singer VALUES( OLD.mem_id, OLD.mem_name, OLD.mem_number,
OLD.addr, '수정', CURDATE(), CURRENT_USER() );
END $$
DELIMITER ;
-- DELETE 삭제 후 작동하는 트리거
DROP TRIGGER IF EXISTS singer_deleteTrg;
DELIMITER $$
CREATE TRIGGER singer_deleteTrg -- 트리거 이름
AFTER DELETE -- 삭제 후에 작동하도록 지정
ON singer -- 트리거를 부착할 테이블
FOR EACH ROW
BEGIN
INSERT INTO backup_singer VALUES( OLD.mem_id, OLD.mem_name, OLD.mem_number,
OLD.addr, '삭제', CURDATE(), CURRENT_USER() );
END $$
DELIMITER ;
(3) 작동
UPDATE singer SET addr = '영국' WHERE mem_id = 'BLK';
DELETE FROM singer WHERE mem_number >= 7;
SELECT * FROM backup_singer;
-- 모든 데이터가 다 지워진다. (백업 테이블에 들어가지 않는다. 즉 트리거를 발생 시키지 않는다.)
TRUNCATE TABLE singer;
SELECT * FROM backup_singer;
728x90