> For the complete documentation index, see [llms.txt](https://docs.tibero.com/tibero-manuals/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tibero.com/tibero-manuals/7.2.6.manuals/development-guide/trigger.md).

# 트리거의 사용

트리거의 기본 개념과 이를 생성하는 방법을 설명합니다.

## 개요

트리거(Trigger)는 스키마 객체의 일종으로, 데이터베이스가 미리 정해 놓은 특정 조건이 만족되거나 어떤 동작이 수행되면 자동으로 실행되도록 정의한 동작입니다. 예를 들어 데이터베이스에 특정한 이벤트가 발생하거나 사용자가 설정한 DDL 문장이 수행될 때 트리거가 실행될 수 있습니다.

트리거의 내용은 PSM으로 이루어져 있습니다. 트리거는 이미 정의된 PSM 객체를 호출하여 사용하거나 트리거를 생성할 때 이름 없는 블록을 함께 선언하는 방식을 모두 이용할 수 있습니다. 트리거 본문을 작성하는 방법과 본문에서 지켜야 할 제약은 "[Tibero tbPSM 안내서](/tibero-manuals/7.2.6.manuals/tbpsm-guide.md)"의 [트리거](/tibero-manuals/7.2.6.manuals/tbpsm-guide/trigger.md)를 참고합니다.

### 트리거 구성 요소

트리거는 다음과 같은 세 가지 구성 요소를 갖춰야만 생성할 수 있습니다.

* 트리거가 실행될 조건이 되는 문장이나 이벤트
* 실행 조건의 제약
* 실행될 내용

다음은 **alarm\_for\_balance**라는 트리거를 생성하는 예입니다.

```
CREATE OR REPLACE TRIGGER alarm_for_balance 
BEFORE INSERT OR UPDATE ON balance_tab                  ... ⓐ ...
FOR EACH ROW
WHEN (new.balance < 3000)                               .. ⓑ ...
      CALL alarm_for_balance_fn()                       .. ⓒ ...
```

ⓐ 테이블 balance\_tab의 balance 컬럼에 로우가 삽입되거나 수정되었을 때 ⓑ로 이동합니다.

ⓑ 해당 로우의 값이 3000 미만인지를 검사합니다.

ⓒ 검사 결과가 조건에 맞으면 alarm\_for\_balance\_fn 함수를 호출하며, 함수에 정의된 동작이 실행됩니다.

### 트리거의 종류

트리거의 종류는 다음과 같이 나눌 수 있습니다.

<table><thead><tr><th width="170">종류</th><th>설명</th></tr></thead><tbody><tr><td>DML 트리거</td><td>테이블에 INSERT, UPDATE, DELETE 문이 수행될 때 실행되는 트리거</td></tr><tr><td>INSTEAD OF 트리거</td><td><ul><li>뷰에 대한 DML 문 대신 실행되는 트리거</li><li>조인 뷰처럼 직접 변경할 수 없는 뷰에 DML 문을 수행할 수 있게 함</li><li>뷰에만 생성할 수 있음</li></ul></td></tr><tr><td>컴파운드 트리거</td><td><ul><li>실행 시점이 다른 여러 섹션을 하나로 묶은 트리거</li><li>모든 섹션이 트리거 선언부의 변수를 공유</li></ul></td></tr><tr><td>DDL 트리거</td><td>스키마 또는 데이터베이스에서 CREATE, DROP, ALTER 등의 DDL 문이 수행될 때 실행되는 트리거</td></tr><tr><td>DB 이벤트 트리거</td><td>LOGON, SERVERERROR, STARTUP 등의 시스템 이벤트가 발생할 때 실행되는 트리거</td></tr></tbody></table>

컴파운드 트리거의 섹션 구성과 실행 순서는 "[Tibero tbPSM 안내서](/tibero-manuals/7.2.6.manuals/tbpsm-guide.md)"의 [트리거](/tibero-manuals/7.2.6.manuals/tbpsm-guide/trigger.md)를, 트리거 종류별 문법과 DDL·DB 이벤트의 전체 목록은 "[Tibero SQL 참조 안내서](/tibero-manuals/7.2.6.manuals/sql-reference-guide.md)"의 [CREATE TRIGGER](/tibero-manuals/7.2.6.manuals/sql-reference-guide/data-definition-language/create-trigger.md)를 참고합니다.

DML 트리거의 타입은 다시 다음과 같이 나눌 수 있습니다.

* 로우(row) 및 문장(statement)

<table><thead><tr><th width="132">타입</th><th>설명</th></tr></thead><tbody><tr><td>로우</td><td><ul><li>테이블에 INSERT, UPDATE, DELETE가 발생하는 로우마다 트리거의 내용이 실행되는 타입</li><li>이 타입의 트리거는 각 로우에 연산이 발생할 때마다 연산 직전 또는 직후에 트리거가 실행됨</li></ul></td></tr><tr><td>문장</td><td>로우의 개수에 상관없이 문장 단위로 한 번만 실행되는 타입</td></tr></tbody></table>

* BEFORE 및 AFTER

<table><thead><tr><th width="135">타입</th><th>설명</th></tr></thead><tbody><tr><td>BEFORE</td><td>조건 문장이 실행되기 전에 트리거의 내용이 실행되는 타입</td></tr><tr><td>AFTER</td><td>조건 문장이 실행된 후 트리거의 내용이 실행되는 타입</td></tr></tbody></table>

트리거는 두 종류의 타입 중에서 하나씩을 각각 가질 수 있습니다. 즉, BEFORE 로우(BEFORE row), BEFORE 문장(BEFORE statement), AFTER 로우(AFTER row), AFTER 문장(AFTER statement)의 타입으로 생성할 수 있습니다.

## 트리거 생성

트리거를 생성하는 방법은 다음과 같습니다.

```
CREATE [OR REPLACE] TRIGGER 트리거_이름
        {BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON 테이블_이름
[FOR EACH ROW]
WHEN (조건_제약)
{[선언부] BEGIN
... END;} |
CALL 함수_또는_프러시저_이름
```

{% hint style="info" %}
**참고**

트리거의 문법에 대한 자세한 내용은 "Tibero SQL 참조 안내서"의 [CREATE TRIGGER](/tibero-manuals/7.2.6.manuals/sql-reference-guide/data-definition-language/create-trigger.md), [ALTER TRIGGER](/tibero-manuals/7.2.6.manuals/sql-reference-guide/data-definition-language/alter-trigger.md), [DROP TRIGGER](/tibero-manuals/7.2.6.manuals/sql-reference-guide/data-definition-language/drop-trigger.md)를 참고합니다.
{% endhint %}

다음은 로우 타입의 트리거로, 테이블 Deck\_tbl의 count 컬럼 값이 1000을 초과할 때마다 Deck\_log 테이블에 로그를 기록하도록 작성한 예입니다.

**\[예 1] 트리거의 생성**

```
CREATE TABLE Deck_tbl (
    Deck_no    NUMBER PRIMARY KEY,
    Deck_name  VARCHAR2(100),
    count      NUMBER
);

-- 로그 테이블 생성 (오버플로우 기록용)
CREATE TABLE Deck_log (
    Deck_id    NUMBER,
    Timestamp  TIMESTAMP,
    New_count  NUMBER,
    Action     VARCHAR2(20)
);

CREATE OR REPLACE TRIGGER Log_overflow
AFTER UPDATE ON Deck_tbl
FOR EACH ROW
WHEN (new.count > 1000)
BEGIN
    INSERT
    INTO Deck_log (Deck_id, Timestamp, New_count, Action)
    VALUES (:new.Deck_no, SYSTIMESTAMP, :new.count, 'overflow');
END;
/

INSERT INTO Deck_tbl VALUES (101, 'Main Deck', 500);
SELECT Deck_id, New_count, Action FROM Deck_log;

UPDATE Deck_tbl SET count = 1200 WHERE Deck_no = 101;
SELECT Deck_id, New_count, Action FROM Deck_log;
```

다음은 실행 결과입니다. INSERT 문은 count 값이 1000 이하이므로 트리거가 실행되지 않고, count 값을 1200으로 바꾸는 UPDATE 문에서 트리거가 실행되어 로그가 기록됩니다.

```
1 row inserted.


0 row selected.


1 row updated.


   DECK_ID  NEW_COUNT ACTION
---------- ---------- --------------------
       101       1200 overflow

1 row selected.
```

CREATE 문장은 Tibero 내부에서 BEGIN – END 사이의 부분을 PSM으로 인식합니다. 이 문장이 컴파일되면 PSM 스키마 객체가 생성되고 이를 데이터베이스에 저장합니다. 컴파일 오류가 발생하면 USER\_ERRORS 뷰를 통해 오류 내용을 확인할 수 있습니다.

생성한 트리거의 정보는 USER\_TRIGGERS, ALL\_TRIGGERS, DBA\_TRIGGERS 뷰에서 조회할 수 있습니다.

## DDL 트리거와 DB 이벤트 트리거

DDL 트리거와 DB 이벤트 트리거는 테이블이 아니라 스키마(ON SCHEMA) 또는 데이터베이스 전체(ON DATABASE)에 연결합니다.

다음은 스키마에 객체가 생성될 때마다 로그를 남기는 DDL 트리거의 예입니다.

**\[예 2] DDL 트리거의 생성**

```
CREATE TABLE ddl_audit_log (
    logged_at  TIMESTAMP,
    log_msg    VARCHAR2(20)
);

CREATE OR REPLACE TRIGGER ddl_audit_trg
AFTER CREATE ON SCHEMA
BEGIN
    INSERT INTO ddl_audit_log VALUES (SYSTIMESTAMP, 'object created');
END;
/

CREATE TABLE ddl_probe_tbl (c1 NUMBER);

SELECT log_msg FROM ddl_audit_log;
```

다음은 실행 결과입니다.

```
LOG_MSG
--------------------
object created

1 row selected.
```

다음은 데이터베이스에서 서버 에러가 발생할 때마다 로그를 남기는 DB 이벤트 트리거의 예입니다.

**\[예 3] DB 이벤트 트리거의 생성**

```
CREATE TABLE err_log_tbl (
    logged_at TIMESTAMP,
    log_msg   VARCHAR2(30)
);

CREATE OR REPLACE TRIGGER err_log_trg
AFTER SERVERERROR ON DATABASE
BEGIN
    INSERT INTO err_log_tbl VALUES (SYSTIMESTAMP, 'server error occurred');
END;
/

SELECT c1 FROM no_such_table;

SELECT log_msg FROM err_log_tbl;
```

다음은 실행 결과입니다.

```
TBR-8033: Specified schema object was not found.
at line 1, column 17 of null:
SELECT c1 FROM no_such_table
               ^


LOG_MSG
------------------------------
server error occurred

1 row selected.
```
