개발/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