• MySQL매뉴얼
    • MySQL 5.6 매뉴얼
    • MySQL 5.1 매뉴얼
    • MySQL 5.0 매뉴얼
    • MySQL HA 매뉴얼
  • 기술문서
    • Xtrabackup 구성
    • 메모리 사용량 모니터링
  • 라이선스
  • 온라인문의
  • 회사소개
  • → 목 록 (MySQL5.6 한글메뉴얼) [close]
  • 1. MySQL 5.6 새로운 기능
  • 2. MySQL 설치 및 업그레이드
  • 3. MySQL Tutorial
  • 4. MySQL 프로그램
  • 5. MySQL 서버관리
  • 6. 보안
  • 7. 백업 및 복구
  • 8. 최적화
  • 9. Language Structure(언어구조)
  • 10. Character Sets(Globalization)
  • 11. 데이터형(Data Types)
  • 12. 함수와 연산자
  • 13. SQL 문법
  • 14. InnoDB 스토리지 엔진
  • 15. 기타 스토리지 엔진
  • 16. 고가용성 및 확장성
  • 17. 리플리케이션
  • 18. MySQL Cluster
  • 19. 파티셔닝
  • 20. Stored Programs and Views
  • 1. Stored Programs 정의
    2. 스토어드 루틴 (프로시저 및 함수)의 사용
    3. 트리거 사용
    1. 트리거 문법 및 예제
    2. 트리거 Metadata
    4. Event Scheduler 사용
    5. Views 사용
    6. Stored Programs 및 Views 액세스 제어
    7. Stored Programs의 Binary Logging
  • 21. INFORMATION_SCHEMA
  • 22. PERFORMANCE SCHEMA
  • 23. 컨넥터 및 API
  • 24. MySQL 확장
  • 25. MySQL Enterprise Edition
  • 26. MySQL Workbench
  • 27. 제약 및 제한
  • 28. MySQL 5.7 새로운 기능

20.3.1 트리거 문법 및 예제

트리거를 만들거나 트리거를 삭제할은 섹션 13.1.19 "CREATE TRIGGER 구문" 및 섹션 13.1.30 "DROP TRIGGER 신텍스" 에서 설명하고있는 바와 같이, CREATE TRIGGER 또는 DROP TRIGGER 문을 사용 합니다.

다음은 INSERT 작업에 활성화 트리거를 테이블에 연관 간단한 예를 보여줍니다. 이 트리거는 가산기로서 기능하고 테이블 중 하나의 컬럼에 삽입 된 값을 합계합니다.

mysql> CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
Query OK, 0 rows affected (0.03 sec)

mysql> CREATE TRIGGER ins_sum BEFORE INSERT ON account
    -> FOR EACH ROW SET @sum = @sum + NEW.amount;
Query OK, 0 rows affected (0.06 sec)

CREATE TRIGGER 문은 account 테이블에 연결된 ins_sum 라는 트리거를 만듭니다. 트리거 동작 시간, 트리거 이벤트 및 트리거가 활성화 될 때 수행 할 작업을 지정하는 조항도 포함되어 있습니다.

  • 키워드 BEFORE 트리거 동작 시간을 나타냅니다. 이 경우 트리거는 테이블에 삽입 된 각 행의 전에 활성화합니다. 여기에서 허용되는 다른 키워드는 AFTER 입니다.

  • 키워드 INSERT 는 트리거 이벤트, 즉 트리거를 활성화하는 형식을 나타냅니다. 예를 들어, INSERT 작업이 트리거의 활성화를 일으 킵니다. DELETE 및 UPDATE 조작에 대한 트리거를 작성할 수 있습니다.

  • FOR EACH ROW 에 오는 명령문은 트리거 내용을 정의합니다. 이것은 트리거가 활성화 될 때마다 실행 문이며, 트리거 이벤트에 의해 영향을받는 행마다 한 번씩 이루어집니다. 이 예에서는 트리거 내용은 amount 컬럼에 삽입 된 값을 사용자 변수에 누적 간단한 SET 입니다. 이 문장은 "새로운 행에 삽입되는 amount 컬럼의 값 "을 의미하는 NEW.amount 로 컬럼을 참조합니다.

트리거를 사용하려면 가산기 변수를 0으로 설정하고 INSERT 문을 실행하여 그 변수가 어떤 값이 있는지 확인합니다.

mysql> SET @sum = 0;
mysql> INSERT INTO account VALUES(137,14.98),(141,1937.50),(97,-100.00);
mysql> SELECT @sum AS 'Total amount inserted';
+-----------------------+
| Total amount inserted |
+-----------------------+
| 1852.48               |
+-----------------------+

이 경우 INSERT 문 실행 후 @sum 값은 14.98 + 1937.50 - 100 또는 1852.48 입니다.

트리거를 삭제하려면 DROP TRIGGER 문을 사용합니다. 트리거가 디폴트 스키마에없는 경우, 스키마 이름을 지정해야합니다.

mysql> DROP TRIGGER test.ins_sum;

테이블을 삭제하면 테이블의 트리거도 삭제됩니다.

트리거 이름은 스키마의 네임 스페이스에 존재합니다. 즉, 모든 트리거가 스키마에서 고유 한 이름을 가져야합니다. 다른 스키마의 트리거는 같은 이름을 가질 수 있습니다.

트리거 이름은 스키마에 대해 고유한다는 요구 사항 이외에 만들 수있는 트리거 유형에 대해 다른 제한이 있습니다. 특히 소정의 테이블에 동일한 트리거 이벤트와 액션 타임을 가진 여러 트리거를 포함 할 수 없습니다. 예를 들어, 하나의 테이블에 2 개의 BEFORE UPDATE 트리거를 정의 할 수 없습니다. 이에 대처하기 위해 FOR EACH ROW 의 후에 BEGIN ... END 복합 문 구조 구문을 사용하여 여러 개의 명령문을 실행하는 트리거를 정의 할 수 있습니다. (예는이 섹션에서 나중에 설명합니다.)

트리거 본체에서 OLD 와 NEW 키워드를 사용하면 트리거의 영향을받는 행의 컬럼에 액세스 할 수 있습니다. OLD 와 NEW 는 트리거에 대한 MySQL의 확장입니다. 이들은 대소 문자를 구별하지 않습니다.

INSERT 트리거 내에서 NEW. col_name 만 사용할 수 있습니다. 오래된 행은 없습니다. DELETE 트리거는 OLD. col_name 만 사용할 수 있습니다. 새로운 라인은 없습니다. UPDATE 트리거는 OLD. col_name 을 사용하여 갱신되기 전에 행의 열을 참조 할 수 있으며 NEW. col_name 을 사용하여 업데이트 된 후에 행의 열을 참조 할 수 있습니다.

OLD 로 지명 된 열은 읽기 전용입니다. (그에 대한 SELECT 권한이있는 경우) 참조 할 수 있지만 수정할 수는 없습니다. NEW 으로 지명 된 컬럼은 그에 대한 SELECT 권한이있는 경우에 볼 수 있습니다. BEFORE 트리거는 그에 대한 UPDATE 권한이있는 경우, SET NEW. col_name = value 로 값을 변경할 수 있습니다. 이것은 트리거를 사용하여 새 행에 삽입 할 값 또는 행의 갱신에 사용되는 값을 변경할 수 있음을 의미합니다. (이러한 SET 문은 행의 변경은 이미 이루어지고 있기 때문에, AFTER 트리거는 효과가 없습니다.)

BEFORE 트리거는 AUTO_INCREMENT 컬럼의 NEW 값은 0이며, 새로운 행이 실제로 삽입 될 때 자동으로 생성되는 시퀀스 번호가 없습니다.

BEGIN ... END 구조 구문을 사용하여 여러 명령문을 실행하는 트리거를 정의 할 수 있습니다. BEGIN 블록 내에서는 조건문과 루프 같은 스토어드 루틴 내에서 허용 된 다른 구문을 사용할 수 있습니다. 그러나 스토어드 루틴의 경우와 마찬가지로, mysql 프로그램을 사용하여 여러 명령문을 실행하는 트리거를 정의 할 때 트리거 정의에서 ; 명령문 구분 문자를 사용할 수 있도록, mysql 문 구분자를 재정의 해야합니다. 다음의 예는 이러한 요점을 보여줍니다. 여기에서 각 행의 업데이트에 사용할 새 값을 확인하고 0에서 100의 범위에 맞게 값을 변경하는 UPDATE 트리거를 정의하고 있습니다. 행의 갱신에 사용되기 전에 값을 체크 할 필요가 있기 때문에 이것은 BEFORE 트리거해야합니다.

mysql> delimiter //
mysql> CREATE TRIGGER upd_check BEFORE UPDATE ON account
    -> FOR EACH ROW
    -> BEGIN
    ->     IF NEW.amount < 0 THEN
    ->         SET NEW.amount = 0;
    ->     ELSEIF NEW.amount > 100 THEN
    ->         SET NEW.amount = 100;
    ->     END IF;
    -> END;//
mysql> delimiter ;

저장 프로 시저를 개별적으로 정의하고 간단한 CALL 문을 사용하여 트리거에서 호출하는 편이 쉬울 때도 있습니다. 이것은 여러 트리거 내에서 동일한 코드를 실행하는 경우에도 유용합니다.

활성화 할 때 트리거가 실행 문에 볼 수 대상에는 제한이 있습니다.

  • 트리거는 CALL 문을 사용하여 데이터를 클라이언트에 반환 저장 프로 시저와 동적 SQL을 사용하는 저장 프로 시저를 호출 할 수 없습니다. (저장 프로시 저는 OUT 또는 INOUT 매개 변수를 통해 트리거 데이터를 돌려주는 것이 허가되어 있습니다.)

  • 트리거는 START TRANSACTION , COMMIT , ROLLBACK 등 트랜잭션을 명시 적 또는 암묵적으로 개시하거나 종료 할 문을 사용할 수 없습니다.

섹션 D.1 "저장 프로그램 제한 사항" 을 참조하십시오.

MySQL은 다음과 같이 트리거 실행 중에 오류를 처리합니다.

  • BEFORE 트리거가 실패 할 경우 해당 행은 수정되지 않습니다.

  • BEFORE 트리거는 행을 삽입하거나 변경하려는 시도에 의해 활성화되고, 그 시도가 그 성공 여부는 중요하지 않습니다.

  • AFTER 트리거는 모든 BEFORE 트리거와 행 조작의 실행이 성공했을 경우에만 실행됩니다.

  • BEFORE 또는 AFTER 트리거 중 하나를 실행하는 동안 오류가 발생하면 트리거의 호출을 발생시킨 명령문 전체가 실패합니다.

  • 트랜잭션 테이블의 경우 문 실패는 문이 실행 한 모든 변경 사항이 롤백됩니다. 트리거의 실패는 문 실패를 초래하므로 트리거의 실패는 롤백도 일으 킵니다. 비 트랜잭션 테이블의 경우 이러한 롤백 할 수 없으므로 명령문이 실패해도 오류 시점 이전에 수행 된 모든 변경은 유효합니다.

다음 예제와 testref 라는 트리거 등 트리거는 이름으로 테이블에 직접 참조를 포함 할 수 있습니다.

CREATE TABLE test1(a1 INT);
CREATE TABLE test2(a2 INT);
CREATE TABLE test3(a3 INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE test4(
  a4 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  b4 INT DEFAULT 0
);

delimiter |

CREATE TRIGGER testref BEFORE INSERT ON test1
  FOR EACH ROW
  BEGIN
    INSERT INTO test2 SET a2 = NEW.a1;
    DELETE FROM test3 WHERE a3 = NEW.a1;
    UPDATE test4 SET b4 = b4 + 1 WHERE a4 = NEW.a1;
  END;
|

delimiter ;

INSERT INTO test3 (a3) VALUES
  (NULL), (NULL), (NULL), (NULL), (NULL),
  (NULL), (NULL), (NULL), (NULL), (NULL);

INSERT INTO test4 (a4) VALUES
  (0), (0), (0), (0), (0), (0), (0), (0), (0), (0);

다음과 같이 테이블 test1 에 다음 값을 삽입합니다.

mysql> INSERT INTO test1 VALUES 
    -> (1), (3), (1), (7), (1), (8), (4), (4);
Query OK, 8 rows affected (0.01 sec)
Records: 8  Duplicates: 0  Warnings: 0

따라서 4 개의 테이블에 다음 데이터가 포함됩니다.

mysql> SELECT * FROM test1;
+------+
| a1   |
+------+
|    1 |
|    3 |
|    1 |
|    7 |
|    1 |
|    8 |
|    4 |
|    4 |
+------+
8 rows in set (0.00 sec)

mysql> SELECT * FROM test2;
+------+
| a2   |
+------+
|    1 |
|    3 |
|    1 |
|    7 |
|    1 |
|    8 |
|    4 |
|    4 |
+------+
8 rows in set (0.00 sec)

mysql> SELECT * FROM test3;
+----+
| a3 |
+----+
|  2 |
|  5 |
|  6 |
|  9 |
| 10 |
+----+
5 rows in set (0.00 sec)

mysql> SELECT * FROM test4;
+----+------+
| a4 | b4   |
+----+------+
|  1 |    3 |
|  2 |    0 |
|  3 |    1 |
|  4 |    2 |
|  5 |    0 |
|  6 |    0 |
|  7 |    1 |
|  8 |    1 |
|  9 |    0 |
| 10 |    0 |
+----+------+
10 rows in set (0.00 sec)


서울시 강남구 영동대로 602 6층
TEL: 02-6061-0006  /  E: csr@mysqlkorea.com
주식회사 이노클러스터  등록번호 : 727-86-02261
Copyright © innocluster Co. ltd. all rights reserved