:meta-keywords: cubrid trigger, database trigger, trigger condition, trigger action, trigger debugging, trigger example :meta-description: CUBRID trigger definition, manipulation and mechanics. ****** 트리거 ****** .. _create-trigger: CREATE TRIGGER ============== 트리거 ì •ì˜ë¥¼ 위한 ê°€ì´ë“œë¼ì¸ ----------------------------- 트리거 ì •ì˜ë¡œ ë‹¤ì–‘í•˜ê³ ê°•ë ¥í•œ ê¸°ëŠ¥ì„ ë§Œë“¤ 수 있다. 트리거를 ìƒì„±í•˜ê¸° ì „ì— ë‹¤ìŒê³¼ ê°™ì€ ì •ì˜ ì‚¬í•ì„ ê³ ë ¤í•´ì•¼ 한다. * **íŠ¸ë¦¬ê±°ì˜ ì¡°ê±´ ì˜ì— 표현ì‹ì´ ë°ì´í„°ë² ì´ìŠ¤ì— ì˜ˆì¸¡í• ìˆ˜ 없는 ê²°ê³¼(side effect)를 ê°€ì ¸ì˜¤ì§€ëŠ” 않는가?** SQL ë¬¸ì„ ì˜ˆì¸¡ì´ ê°€ëŠ¥í•œ 범위 ë‚´ì—ì„œ 사용해야 한다. * **íŠ¸ë¦¬ê±°ì˜ ì‹¤í–‰ ì˜ì—ì´ íŠ¸ë¦¬ê±°ì˜ ì´ë²¤íŠ¸ 대ìƒìœ¼ë¡œ 주어진 í…Œì´ë¸”ì„ ë³€ê²½í•˜ì§€ëŠ” 않는가?** ì´ëŸ¬í•œ ìœ í˜•ì˜ ì„¤ê³„ê°€ íŠ¸ë¦¬ê±°ì˜ ì •ì˜ì—ì„œ ì‚¬ìš©ì´ ê¸ˆì§€ë˜ì–´ 있지는 않지만, 무한 루프로 ë¹ ì§€ëŠ” 트리거가 만들어질 수 있어 주ì˜í•´ì„œ 사용해야 한다. 트리거 실행 ì˜ì—ì´ ì´ë²¤íŠ¸ ëŒ€ìƒ í…Œì´ë¸”ì„ ìˆ˜ì •í• ë•Œ, ê°™ì€ íŠ¸ë¦¬ê±°ê°€ 다시 ë¶ˆë ¤ì§ˆ 수 있다. ë˜í•œ **WHERE** ì ˆì„ í¬í•¨í•˜ëŠ” ë¬¸ìž¥ì— ì˜í•´ 트리거가 ë°œìƒí•˜ë©´, 해당 트리거는 **WHERE** ì ˆì— ì˜í•´ 수행ë˜ëŠ” í…Œì´ë¸”ì—는 ì¼ë°˜ì 으로 ë¶€ìž‘ìš©ì´ ì—†ë‹¤. * **트리거가 불필요한 오버헤드를 만들어 ë‚´ê³ ìžˆì§€ëŠ” 않는가?** ì›í•˜ëŠ” ë™ìž‘ì´ ì†ŒìŠ¤ ë‚´ì—ì„œ 조금 ë” íš¨ê³¼ì 으로 표현ë 수 있다면 ì§ì ‘ 소스 ë‚´ì—ì„œ 구현하ë„ë¡ í•œë‹¤. * **트리거가 재귀ì 으로 실행ë˜ê³ 있지는 않는가?** íŠ¸ë¦¬ê±°ì˜ ì‹¤í–‰ ì˜ì—ì´ íŠ¸ë¦¬ê±°ë¥¼ ë¶€ë¥´ê³ ì´ íŠ¸ë¦¬ê±°ê°€ 다시 ì²˜ìŒ íŠ¸ë¦¬ê±°ë¥¼ 부르면 재귀 루프(recursive loop)ê°€ ë°ì´í„°ë² ì´ìŠ¤ì— 만들어진다. 재귀 루프가 만들어지면, 트리거가 ì •í™•ížˆ 수행ë˜ì§€ 않거나 진행 ì¤‘ì¸ ë£¨í”„ë¥¼ ë‹¨ì ˆí•˜ê¸° 위해 현재 ì„¸ì…˜ì„ ê°•ì œë¡œ 종료해야 í• ìˆ˜ë„ ìžˆë‹¤. * **íŠ¸ë¦¬ê±°ì˜ ì •ì˜ëŠ” ìœ ì¼í•œê°€?** ë™ì¼í•œ í…Œì´ë¸”ì—ì„œ ì •ì˜ëœ 트리거나, ë™ì¼í•œ 실행 ì˜ì—ì—ì„œ ì‹œìž‘ëœ íŠ¸ë¦¬ê±°ëŠ” ë³µêµ¬í• ìˆ˜ 없는 ì—ëŸ¬ì˜ ì›ì¸ì´ ëœë‹¤. ë™ì¼í•œ í…Œì´ë¸”ì— ìžˆëŠ” 트리거는 다른 트리거 ì´ë²¤íŠ¸ë¥¼ ê°€ì ¸ì•¼ 한다. ë˜í•œ, íŠ¸ë¦¬ê±°ì˜ ìš°ì„ ìˆœìœ„ëŠ” 명시ì 으로 ì •ì˜ë˜ì–´ 있거나 모호하지 않아야 한다. 트리거 ì •ì˜ êµ¬ë¬¸ ---------------- **CREATE TRIGGER** ë¬¸ì„ ì‚¬ìš©í•˜ì—¬ 새로운 트리거를 ìƒì„±í•˜ê³ , 트리거 대ìƒ, 실행 ì¡°ê±´ê³¼ ìˆ˜í–‰í• ë‚´ìš©ì„ ì •ì˜í• 수 있다. 트리거는 ë°ì´í„°ë² ì´ìŠ¤ ê°ì²´ë¡œì„œ, íŠ¹ì • ì´ë²¤íŠ¸ê°€ ëŒ€ìƒ í…Œì´ë¸”ì— ëŒ€í•´ ë°œìƒí•˜ë©´ ì •ì˜ëœ ë™ìž‘ì„ ìˆ˜í–‰í•œë‹¤. :: CREATE TRIGGER [schema_name.]trigger_name [ STATUS { ACTIVE | INACTIVE } ] [ PRIORITY key ] <event_time> <event_type> [<event_target>] [ IF condition ] EXECUTE [ AFTER | DEFERRED ] action [COMMENT 'trigger_comment']; <event_time> ::= BEFORE | AFTER | DEFERRED <event_type> ::= INSERT | STATEMENT INSERT | UPDATE | STATEMENT UPDATE | DELETE | STATEMENT DELETE | ROLLBACK | COMMIT <event_target> ::= ON [schema_name.]table_name | ON [schema_name.]table_name [ (column_name) ] <condition> ::= expression <action> ::= REJECT | INVALIDATE TRANSACTION | PRINT message_string | INSERT statement | UPDATE statement | DELETE statement * *schema_name*: íŠ¸ë¦¬ê±°ì˜ ìŠ¤í‚¤ë§ˆ ì´ë¦„ì„ ì§€ì •í•œë‹¤. ìƒëžµí•˜ë©´ 현재 ì„¸ì…˜ì˜ ìŠ¤í‚¤ë§ˆ ì´ë¦„ì„ ì‚¬ìš©í•œë‹¤. * *trigger_name*: ì •ì˜í•˜ë ¤ëŠ” íŠ¸ë¦¬ê±°ì˜ ì´ë¦„ì„ ì§€ì •í•œë‹¤. * [ **STATUS** { **ACTIVE** | **INACTIVE** } ]: íŠ¸ë¦¬ê±°ì˜ ìƒíƒœë¥¼ ì •ì˜í•œë‹¤(ì •ì˜í•˜ì§€ ì•Šì„ ê²½ìš° ê¸°ë³¸ê°’ì€ **ACTIVE** ). * **ACTIVE** ìƒíƒœì¸ 경우 ê´€ë ¨ ì´ë²¤íŠ¸ê°€ ë°œìƒí• 때마다 트리거를 실행한다. * **INACTIVE** ìƒíƒœì¸ 경우 ê´€ë ¨ ì´ë²¤íŠ¸ê°€ ë°œìƒí•˜ì—¬ë„ 트리거를 실행하지 않는다. íŠ¸ë¦¬ê±°ì˜ í™œì„± 여부는 ë³€ê²½í• ìˆ˜ 있다. ìžì„¸í•œ ë‚´ìš©ì€ :ref:`alter-trigger` ì„ ì°¸ì¡°í•œë‹¤. * [ **PRIORITY** *key* ]: í•˜ë‚˜ì˜ ì´ë²¤íŠ¸ì— 대해서 ë‹¤ìˆ˜ì˜ íŠ¸ë¦¬ê±°ê°€ ë¶ˆë ¤ì§ˆ 경우 실행ë˜ëŠ” ìš°ì„ ìˆœìœ„ë¥¼ 부여한다. *key* ê°’ì€ ë°˜ë“œì‹œ ìŒìˆ˜ê°€ ì•„ë‹Œ ë¶€ë™ ì†Œìˆ˜ì ê°’ì´ì–´ì•¼ 한다. ìš°ì„ ìˆœìœ„ë¥¼ ì •ì˜í•˜ì§€ ì•Šì„ ê²½ìš° 가장 ë‚®ì€ ìš°ì„ ìˆœìœ„ì¸ 0ì„ í• ë‹¹í•œë‹¤. ê°™ì€ ìš°ì„ ìˆœìœ„ë¥¼ 가지는 트리거는 ìž„ì˜ì˜ 순서로 실행ëœë‹¤. íŠ¸ë¦¬ê±°ì˜ ìš°ì„ ìˆœìœ„ëŠ” ë³€ê²½í• ìˆ˜ 있다. ìžì„¸í•œ ë‚´ìš©ì€ :ref:`alter-trigger` ì„ ì°¸ì¡°í•œë‹¤. * <*event_time*>: íŠ¸ë¦¬ê±°ì˜ ì¡°ê±´ ì˜ì—ê³¼ 실행 ì˜ì—ì´ ì‹¤í–‰ë˜ëŠ” ì‹œì ì„ ì§€ì •í•˜ë©° **BEFORE**, **AFTER**, **DEFERRED** ê°€ 있다. ìžì„¸í•œ ë‚´ìš©ì€ :ref:`trigger-event-time` ì„ ì°¸ì¡°í•œë‹¤. * <*event_type*>: 트리거 íƒ€ìž…ì€ ì‚¬ìš©ìž íŠ¸ë¦¬ê±°ì™€ í…Œì´ë¸” 트리거로 나뉜다. ìžì„¸í•œ ë‚´ìš©ì€ :ref:`trigger-event-type` ì„ ì°¸ì¡°í•œë‹¤. * <*event_target*>: ì´ë²¤íŠ¸ 대ìƒì€ 트리거가 호출ë˜ê¸° 위한 대ìƒì„ ì§€ì •í• ë•Œ ì“°ì¸ë‹¤. ìžì„¸í•œ ë‚´ìš©ì€ :ref:`trigger-event-target` ì„ ì°¸ì¡°í•œë‹¤. * <*condition*>: íŠ¸ë¦¬ê±°ì˜ ì¡°ê±´ì˜ì—ì„ ì§€ì •í•œë‹¤. ìžì„¸í•œ ë‚´ìš©ì€ :ref:`trigger-condition` ì„ ì°¸ì¡°í•œë‹¤. * <*action*>: íŠ¸ë¦¬ê±°ì˜ ì‹¤í–‰ì˜ì—ì„ ì§€ì •í•œë‹¤. ìžì„¸í•œ ë‚´ìš©ì€ :ref:`trigger-action` ì„ ì°¸ì¡°í•œë‹¤. * *trigger_comment*: íŠ¸ë¦¬ê±°ì˜ ì»¤ë©˜íŠ¸ë¥¼ ì§€ì •í•œë‹¤. .. note:: * **DBA** 와 **DBA** 멤버는 다른 ìŠ¤í‚¤ë§ˆì— íŠ¸ë¦¬ê±°ë¥¼ ìƒì„±í• 수 있다. 사용ìžê°€ **DBA** ë„ ì•„ë‹ˆê³ **DBA** ë©¤ë²„ë„ ì•„ë‹ˆë©´ 해당 사용ìžì˜ 스키마ì—서만 트리거를 ìƒì„±í• 수 있다. 다ìŒì€ *participant* í…Œì´ë¸”ì˜ ë ˆì½”ë“œë¥¼ ê°±ì‹ í• ë•Œ íšë“ ë©”ë‹¬ì˜ ê°œìˆ˜ê°€ 0보다 ìž‘ì„ ê²½ìš° ê°±ì‹ ì„ ê±°ì ˆí•˜ëŠ” 트리거를 ìƒì„±í•˜ëŠ” ì˜ˆì œì´ë‹¤. 2004ë…„ë„ ì˜¬ë¦¼í”½ì— í•œêµì´ íšë“í•œ ê¸ˆë©”ë‹¬ì˜ ê°œìˆ˜ë¥¼ ìŒìˆ˜ë¡œ ê°±ì‹ í• ê²½ìš° ê°±ì‹ ì´ ê±°ì ˆë˜ëŠ” ê²ƒì„ ì•Œ 수 있다. .. code-block:: sql CREATE TRIGGER medal_trigger BEFORE UPDATE ON participant IF new.gold < 0 OR new.silver < 0 OR new.bronze < 0 EXECUTE REJECT; UPDATE participant SET gold = -5 WHERE nation_code = 'KOR' AND host_year = 2004; :: ERROR: The operation has been rejected by trigger "medal_trigger". .. _trigger-event-time: ì´ë²¤íŠ¸ ì‹œì ----------- íŠ¸ë¦¬ê±°ì˜ ì¡°ê±´ ì˜ì—ê³¼ 실행 ì˜ì—ì´ ì‹¤í–‰ë˜ëŠ” ì‹œì ì„ ì§€ì •í•œë‹¤. ì´ë²¤íŠ¸ ì‹œì ì˜ ì¢…ë¥˜ì—는 **BEFORE**, **AFTER**, **DEFERRED** ê°€ 있다. * **BEFORE**: ì´ë²¤íŠ¸ê°€ 처리ë˜ê¸° ì „ì— ì¡°ê±´ì„ ê²€ì‚¬í•œë‹¤. * **AFTER**: ì´ë²¤íŠ¸ê°€ ì²˜ë¦¬ëœ í›„ì— ì¡°ê±´ì„ ê²€ì‚¬í•œë‹¤. * **DEFERRED**: ì´ë²¤íŠ¸ì— 대한 트랜ìžì…˜ì˜ ëì—ì„œ ì¡°ê±´ì„ ê²€ì‚¬í•œë‹¤. **DEFERRED** ë¡œ ì§€ì •í• ê²½ìš° ì´ë²¤íŠ¸ íƒ€ìž…ì— **COMMIT** ì´ë‚˜ **ROLLBACK** ì„ ì‚¬ìš©í• ìˆ˜ 없다. 트리거 타입 ----------- **ì‚¬ìš©ìž íŠ¸ë¦¬ê±°(User Trigger)** * ë°ì´í„°ë² ì´ìŠ¤ì˜ íŠ¹ì • 사용ìžì™€ ê´€ë ¨ëœ íŠ¸ë¦¬ê±°ë¥¼ ì‚¬ìš©ìž íŠ¸ë¦¬ê±°(user trigger)ë¼ê³ 한다. * ì‚¬ìš©ìž íŠ¸ë¦¬ê±°ëŠ” ì´ë²¤íŠ¸ 대ìƒì´ 없으며 íŠ¸ë¦¬ê±°ì˜ ì†Œìœ ìž(트리거를 ìƒì„±í•œ 사용ìž)ì— ì˜í•´ì„œë§Œ 실행ëœë‹¤. * ì‚¬ìš©ìž íŠ¸ë¦¬ê±°ë¥¼ ì •ì˜í•˜ëŠ” ì´ë²¤íŠ¸ íƒ€ìž…ì€ **COMMIT** ê³¼ **ROLLBACK** ì´ ìžˆë‹¤. **í…Œì´ë¸” 트리거(Table Trigger)** * íŠ¹ì • í…Œì´ë¸”ì„ ì´ë²¤íŠ¸ 대ìƒìœ¼ë¡œ 가지는 트리거를 í…Œì´ë¸” 트리거(í´ëž˜ìŠ¤ 트리거)ë¼ í•œë‹¤. * í…Œì´ë¸” 트리거는 ëŒ€ìƒ í…Œì´ë¸”ì— **SELECT** ê¶Œí•œì„ ê°€ì§€ëŠ” ëª¨ë“ ì‚¬ìš©ìžê°€ ë³¼ 수 있다. * í…Œì´ë¸” 트리거를 ì •ì˜í•˜ëŠ” ì´ë²¤íŠ¸ íƒ€ìž…ì€ ì¸ìŠ¤í„´ìŠ¤ ì´ë²¤íŠ¸ì™€ 문장 ì´ë²¤íŠ¸ê°€ 있다. .. _trigger-event-type: 트리거 ì´ë²¤íŠ¸ 타입 ------------------ * ì¸ìŠ¤í„´ìŠ¤ ì´ë²¤íŠ¸(instance event) : ì¸ìŠ¤í„´ìŠ¤ ì´ë²¤íŠ¸ëŠ” ì´ë²¤íŠ¸ ì—°ì‚°ì˜ ë‹¨ìœ„ê°€ ì¸ìŠ¤í„´ìŠ¤(ë ˆì½”ë“œ)ì¸ ì´ë²¤íŠ¸ íƒ€ìž…ì„ ë§í•œë‹¤. ì¸ìŠ¤í„´ìŠ¤ ì´ë²¤íŠ¸ì˜ 종류는 다ìŒê³¼ 같다. * **INSERT** * **UPDATE** * **DELETE** * 문장 ì´ë²¤íŠ¸(statement event): ì´ë²¤íŠ¸ íƒ€ìž…ì„ ë¬¸ìž¥ ì´ë²¤íŠ¸ë¡œ ì •ì˜í•˜ë©´ 주어진 문장(ì´ë²¤íŠ¸)ì— ì˜í•´ ì˜í–¥ì„ 받는 ê°ì²´(ì¸ìŠ¤í„´ìŠ¤)ê°€ 많ë”ë¼ë„, 트리거는 ë¬¸ìž¥ì´ ì‹œìž‘í• ë•Œ í•œ 번만 ë¶ˆë ¤ì§€ê²Œ ëœë‹¤. 문장 ì´ë²¤íŠ¸ì˜ 종류는 다ìŒê³¼ 같다. * **STATEMENT INSERT** * **STATEMENT UPDATE** * **STATEMENT DELETE** * 기타 ì´ë²¤íŠ¸: **COMMIT** ê³¼ **ROLLBACK** ì€ ê°œë³„ì ì¸ ì¸ìŠ¤í„´ìŠ¤ì—는 ì ìš©í• ìˆ˜ 없다. * **COMMIT** * **ROLLBACK** 다ìŒì€ ì¸ìŠ¤í„´ìŠ¤ ì´ë²¤íŠ¸ë¥¼ 사용하는 ì˜ˆì œì´ë‹¤. *example* 트리거는 ë°ì´í„°ë² ì´ìŠ¤ ê°±ì‹ ì— ì˜í•´ ì˜í–¥ì„ 받는 ê°ê°ì˜ ì¸ìŠ¤í„´ìŠ¤ì— 대해서 한번씩 ë¶ˆë ¤ì§„ë‹¤. 예를 들어, *history* í…Œì´ë¸”ì˜ ë‹¤ì„¯ ê°œ ì¸ìŠ¤í„´ìŠ¤ì˜ *score* 를 변경했다면, ì´ íŠ¸ë¦¬ê±°ëŠ” 다섯 번 ë¶ˆë ¤ì§„ë‹¤. .. code-block:: sql CREATE TABLE update_logs(event_code INTEGER, score VARCHAR(10), dt DATETIME); CREATE TRIGGER example BEFORE UPDATE ON history(score) EXECUTE INSERT INTO update_logs VALUES (obj.event_code, obj.score, SYSDATETIME); 만약 *score* ì¹¼ëŸ¼ì˜ ì²« 번째 ì¸ìŠ¤í„´ìŠ¤ê°€ ê°±ì‹ ë˜ê¸° ì „ì— íŠ¸ë¦¬ê±°ê°€ í•œ 번만 호출ë˜ê²Œ í•˜ë ¤ë©´, ì•„ëž˜ì˜ ì˜ˆì™€ ê°™ì´ **STATEMENT UPDATE** 형ì‹ì„ 사용한다. 다ìŒì€ 문장 ì´ë²¤íŠ¸ë¥¼ 사용하는 ì˜ˆì œì´ë‹¤. 문장 ì´ë²¤íŠ¸ë¥¼ ì§€ì •í•˜ë©´ ê°±ì‹ ì˜ ì˜í–¥ì„ 받는 ì¸ìŠ¤í„´ìŠ¤ê°€ 많ë”ë¼ë„, 첫 번째 ì¸ìŠ¤í„´ìŠ¤ê°€ ê°±ì‹ ë˜ê¸° ì „ì— íŠ¸ë¦¬ê±°ê°€ í•œ 번만 ë¶ˆë ¤ì§€ê²Œ ëœë‹¤. .. code-block:: sql CREATE TRIGGER example BEFORE STATEMENT UPDATE ON history(score) EXECUTE PRINT 'There was an update on history table'; .. note:: * ì´ë²¤íŠ¸ 타입으로 ì¸ìŠ¤í„´ìŠ¤ ì´ë²¤íŠ¸ì™€ 문장 ì´ë²¤íŠ¸ë¥¼ ì§€ì •í• ê²½ìš°ì—는 반드시 ì´ë²¤íŠ¸ 대ìƒì„ 명시해야 한다. * **COMMIT** ê³¼ **ROLLBACK** ì€ ì´ë²¤íŠ¸ 대ìƒì„ 가질 수 없다. .. _trigger-event-target: 트리거 ì´ë²¤íŠ¸ ëŒ€ìƒ ------------------ ì´ë²¤íŠ¸ 대ìƒì€ 트리거가 호출ë˜ê¸° 위한 대ìƒì„ ì§€ì •í• ë•Œ ì“°ì¸ë‹¤. 트리거 ì´ë²¤íŠ¸ì˜ 대ìƒì€ í…Œì´ë¸”명 í˜¹ì€ í…Œì´ë¸”명과 칼럼명으로 ì§€ì •í• ìˆ˜ 있으며 ì¹¼ëŸ¼ëª…ì„ ì§€ì •í•˜ë©´ 해당 ì¹¼ëŸ¼ì´ ì´ë²¤íŠ¸ì˜ ì˜í–¥ì„ ë°›ì„ ë•Œì—만 트리거가 ë¶ˆë ¤ì§„ë‹¤. 만약 ì¹¼ëŸ¼ì„ ì§€ì •í•˜ì§€ 않으면 ì§€ì •ëœ í…Œì´ë¸” ë‚´ì— ì–´ë–¤ ì¹¼ëŸ¼ì´ ì˜í–¥ì„ ë°›ë”ë¼ë„ 트리거가 호출ëœë‹¤. ì˜¤ì§ **UPDATE**, **STATEMENT UPDATE** ì´ë²¤íŠ¸ë§Œì´ ì´ë²¤íŠ¸ 대ìƒì— ì¹¼ëŸ¼ì„ ì§€ì •í• ìˆ˜ 있다. 다ìŒì€ *example* íŠ¸ë¦¬ê±°ì˜ ì´ë²¤íŠ¸ 대ìƒì„ *history* í…Œì´ë¸”ì˜ *score* 칼럼으로 ì§€ì •í•œ ì˜ˆì œì´ë‹¤. .. code-block:: sql CREATE TABLE update_logs(event_code INTEGER, score VARCHAR(10), dt DATETIME); CREATE TRIGGER example BEFORE UPDATE ON history(score) EXECUTE INSERT INTO update_logs VALUES (obj.event_code, obj.score, SYSDATETIME); ì´ë²¤íŠ¸ 타입과 ëŒ€ìƒ ì¡°í•© ----------------------- 트리거를 호출하는 ë°ì´í„°ë² ì´ìŠ¤ ì´ë²¤íŠ¸ëŠ” 트리거 ì´ë²¤íŠ¸ 타입과 트리거 ì •ì˜ ë‚´ì˜ ì´ë²¤íŠ¸ 대ìƒì— ì˜í•´ ì‹ë³„ëœë‹¤. 다ìŒì€ 트리거 ì´ë²¤íŠ¸ 타입과 ëŒ€ìƒ ì¡°í•©, 트리거 ì´ë²¤íŠ¸ê°€ 나타내는 CUBRID ë°ì´í„°ë² ì´ìŠ¤ ì´ë²¤íŠ¸ì˜ 활ë™ì„ 표로 ì •ë¦¬í•œ 것ì´ë‹¤. +--------------+--------------+-----------------------------------------------------------------+ | ì´ë²¤íŠ¸ 타입 | ì´ë²¤íŠ¸ ëŒ€ìƒ | 대ì‘ë˜ëŠ” ë°ì´í„°ë² ì´ìŠ¤ í™œë™ | +==============+==============+=================================================================+ | **UPDATE** | í…Œì´ë¸” | í…Œì´ë¸”ì— **UPDATE** ë¬¸ì´ ì‹¤í–‰ë˜ì—ˆì„ ë•Œ 트리거가 호출ëœë‹¤. | +--------------+--------------+-----------------------------------------------------------------+ | **INSERT** | í…Œì´ë¸” | í…Œì´ë¸”ì— **INSERT** ë¬¸ì´ ì‹¤í–‰ë˜ì—ˆì„ ë•Œ 트리거가 호출ëœë‹¤. | +--------------+--------------+-----------------------------------------------------------------+ | **DELETE** | í…Œì´ë¸” | í…Œì´ë¸”ì— **DELETE** ë¬¸ì´ ì‹¤í–‰ë˜ì—ˆì„ ë•Œ 트리거가 호출ëœë‹¤. | +--------------+--------------+-----------------------------------------------------------------+ | **COMMIT** | ì—†ìŒ | ë°ì´í„°ë² ì´ìŠ¤ 트랜ìžì…˜ì´ 커밋ë˜ì—ˆì„ ë•Œ 트리거가 호출ëœë‹¤. | +--------------+--------------+-----------------------------------------------------------------+ | **ROLLBACK** | ì—†ìŒ | ë°ì´í„°ë² ì´ìŠ¤ì˜ 트랜ìžì…˜ì´ 롤백ë˜ì—ˆì„ ë•Œ 트리거가 호출ëœë‹¤. | +--------------+--------------+-----------------------------------------------------------------+ .. _trigger-condition: 트리거 ì¡°ê±´ ì˜ì— ---------------- 트리거를 ì •ì˜í• ë•Œ ì¡°ê±´ ì˜ì—ì„ ì •ì˜í•˜ì—¬ íŠ¸ë¦¬ê±°ì˜ ìˆ˜í–‰ ì˜ì—ì— ëŒ€í•œ 수행 여부를 ê²°ì •í•œë‹¤. * 트리거 ì¡°ê±´ ì˜ì—ì´ ê¸°ìˆ ëœë‹¤ë©´, ì°¸ ë˜ëŠ” ê±°ì§“ì„ í‰ê°€í• 수 있는 단ë…ì ì¸ ë³µí•© 표현ì‹ìœ¼ë¡œ 쓰여질 수 있다. ì´ ê²½ìš°ì— í‘œí˜„ì‹ì€ **SELECT** ë¬¸ì˜ **WHERE** ì ˆì— í—ˆìš©ë˜ëŠ” ì‚°ìˆ ì—°ì‚°ìžì™€ 논리 ì—°ì‚°ìžë¥¼ í¬í•¨í• 수 있다. ì¡°ê±´ ì˜ì—ì´ ì°¸ì´ë©´, 트리거 실행 ì˜ì—ì´ ìˆ˜í–‰ë˜ê³ , 거짓ì´ë©´ 실행ë˜ì§€ 않는다. * íŠ¸ë¦¬ê±°ì˜ ì¡°ê±´ ì˜ì—ì„ ìƒëžµí•˜ë©´ ì¡°ê±´ 없는 트리거(unconditional trigger)ê°€ ë˜ë©° 트리거가 호출ë ë•Œ í•ìƒ íŠ¸ë¦¬ê±°ì˜ ì‹¤í–‰ ì˜ì—ì´ ìˆ˜í–‰ëœë‹¤. 다ìŒì€ ì¡°ê±´ ì˜ì— ë‚´ì˜ í‘œí˜„ì‹ì— ìƒê´€ëª…ì„ ì´ìš©í•œ ì˜ˆì œì´ë‹¤. ì´ë²¤íŠ¸ íƒ€ìž…ì´ **INSERT**, **UPDATE**, **DELETE** ì¸ ê²½ìš°ì—, ì¡°ê±´ ì˜ì— ë‚´ì˜ í‘œí˜„ì‹ì€ íŠ¹ì • 칼럼 ê°’ì— ì ‘ê·¼í•˜ê¸° 위하여 ìƒê´€ëª… **obj**, **new**, **old** 를 ì‚¬ìš©í• ìˆ˜ 있다. ì˜ˆì œì—ì„œ *example* 트리거는 ì¹¼ëŸ¼ì˜ ìƒˆë¡œìš´ ê°’ì„ ì´ìš©í•´ì„œ ì¡°ê±´ ì˜ì—ì„ ê²€ì‚¬í•˜ê¸° 위해 트리거 ì¡°ê±´ ì˜ì—ì— **new** 를 칼럼 ì´ë¦„ ì•žì— ì‚¬ìš©í•˜ì˜€ë‹¤. .. code-block:: sql CREATE TRIGGER example BEFORE UPDATE ON participant IF new.gold < 0 OR new.silver < 0 OR new.bronze < 0 EXECUTE REJECT; 다ìŒì€ ì¡°ê±´ ì˜ì— ë‚´ì˜ í‘œí˜„ì‹ì— **SELECT** ë¬¸ì„ ì‚¬ìš©í•œ ì˜ˆì œì´ë‹¤. ì˜ˆì œì˜ íŠ¸ë¦¬ê±°ëŠ” 집계함수 **COUNT** (\*)를 사용하는 **SELECT** ë¬¸ì„ ì‚¬ìš©í•˜ì—¬ ê·¸ ê°’ê³¼ ìƒìˆ˜ë¥¼ 비êµí•œë‹¤. **SELECT** ë¬¸ì€ ë°˜ë“œì‹œ 괄호로 싸여 있어야 í•˜ê³ , 표현ì‹ì˜ ë§ˆì§€ë§‰ì— ìœ„ì¹˜í•´ì•¼ 한다. .. code-block:: sql CREATE TRIGGER example BEFORE INSERT ON participant IF 1000 > (SELECT COUNT(*) FROM participant) EXECUTE REJECT; .. note:: 트리거 ì¡°ê±´ ì˜ì—ì— ì£¼ì–´ì§„ 표현ì‹ì€ ì¡°ê±´ ì˜ì—ì´ ìˆ˜í–‰ë˜ëŠ” ë™ì•ˆì— 메서드가 호출ë˜ë©´ ë°ì´í„°ë² ì´ìŠ¤ì— ë¶€ìž‘ìš©ì„ ì´ˆëž˜í• ìˆ˜ 있다. 트리거 ì¡°ê±´ ì˜ì—ì€ ë°ì´í„°ë² ì´ìŠ¤ì— ìƒê°ì§€ 못한 ë¶€ìž‘ìš©ì´ ë°œìƒí•˜ì§€ ì•Šë„ë¡ êµ¬ì„±í•´ì•¼ 한다. ìƒê´€ëª…(correlation name) ------------------------ 트리거를 ì •ì˜í• ë•Œ ìƒê´€ëª…ì„ ì‚¬ìš©í•˜ì—¬ ëŒ€ìƒ í…Œì´ë¸”ì˜ ì¹¼ëŸ¼ ê°’ì— ì ‘ê·¼í• ìˆ˜ 있다. ìƒê´€ëª…ì€ ì‹¤ì œì 으로 트리거를 부르는 ë°ì´í„°ë² ì´ìŠ¤ ì—°ì‚°ì— ì˜í•´ ì˜í–¥ì„ 받는 ì¸ìŠ¤í„´ìŠ¤ë¥¼ 나타낸다. ìƒê´€ëª…ì€ íŠ¸ë¦¬ê±°ì˜ ì¡°ê±´ ì˜ì—ì´ë‚˜ 실행 ì˜ì—ì—ë„ ê¸°ìˆ í• ìˆ˜ 있다. ìƒê´€ëª…ì˜ ì¢…ë¥˜ì—는 **new**, **old**, **obj** ê°€ 있으며 ì´ëŸ¬í•œ ìƒê´€ëª…ì€ ì¸ìŠ¤í„´ìŠ¤ 트리거ì—ì„œ **INSERT**, **UPDATE**, **DELETE** ì˜ ì´ë²¤íŠ¸ íƒ€ìž…ì„ ê°€ì§€ê³ ìžˆëŠ” 트리거ì—서만 ì‚¬ìš©í• ìˆ˜ 있다. ìƒê´€ëª…ì˜ ì‚¬ìš©ì€ ì•„ëž˜ 표와 ê°™ì´ íŠ¸ë¦¬ê±° ì¡°ê±´ ì˜ì—ì— ì •ì˜ëœ ì´ë²¤íŠ¸ ì‹œì ì— ì˜í•´ ë”ìš± ì œí•œëœë‹¤. +------------+------------+-----------------------+ | | BEFORE | AFTER or DERERRED | +============+============+=======================+ | **INSERT** | **new** | **obj** | +------------+------------+-----------------------+ | **UPDATE** | **obj** | **obj** | | | | | | | **new** | **old** (AFTER) | +------------+------------+-----------------------+ | **DELETE** | **obj** | N/A | +------------+------------+-----------------------+ +---------+-------------------------------------------------------------------------------------------------------------+ | ìƒê´€ëª… | 대표 ì†ì„± ê°’ | +=========+=============================================================================================================+ | **obj** | ì¸ìŠ¤í„´ìŠ¤ì˜ 현재 ì†ì„± ê°’ì„ ë‚˜íƒ€ë‚¸ë‹¤. ì¸ìŠ¤í„´ìŠ¤ê°€ ê°±ì‹ ë˜ê±°ë‚˜ ì‚ì œë˜ê¸° ì „ì— ì†ì„±ê°’ì— ì ‘ê·¼í•˜ê¸° 위해서 사용한다. | | | ê·¸ë¦¬ê³ ì¸ìŠ¤í„´ìŠ¤ê°€ ê°±ì‹ ë˜ê±°ë‚˜ ì‚½ìž…ëœ í›„ì— ì†ì„± ê°’ì— ì ‘ê·¼í•˜ê¸° 위해 사용한다. | +---------+-------------------------------------------------------------------------------------------------------------+ | **new** | 삽입ì´ë‚˜ ê°±ì‹ ì—°ì‚°ì— ì˜í•´ ì œì‹œë˜ëŠ” ì†ì„±ê°’ì„ ë‚˜íƒ€ë‚¸ë‹¤. | | | 새로운 ê°’ì€ ì¸ìŠ¤í„´ìŠ¤ê°€ ì‹¤ì œì 으로 삽입ë˜ê±°ë‚˜ ê°±ì‹ ë˜ê¸° ì „ì—만 ì ‘ê·¼í• ìˆ˜ 있다. | +---------+-------------------------------------------------------------------------------------------------------------+ | **old** | ê°±ì‹ ì—°ì‚°ì˜ ì™„ë£Œ ì „ì— ì¡´ìž¬í•˜ë˜ ì†ì„±ê°’ì„ ë‚˜íƒ€ë‚¸ë‹¤. ì´ ê°’ì€ íŠ¸ë¦¬ê±°ê°€ 수행ë˜ëŠ” ë™ì•ˆë§Œ ìœ ì§€ëœë‹¤. | | | 트리거가 종료ë˜ë©´ **old** ê°’ì€ ìžƒì–´ë²„ë¦¬ê²Œ ëœë‹¤. | +---------+-------------------------------------------------------------------------------------------------------------+ .. _trigger-action: 트리거 실행 ì˜ì— ---------------- 트리거 실행 ì˜ì—ì€ íŠ¸ë¦¬ê±°ì˜ ì¡°ê±´ ì˜ì—ì´ ì°¸ì´ê±°ë‚˜ ì¡°ê±´ ì˜ì—ì´ ìƒëžµëœ 경우 수행ë ë‚´ìš©ì„ ê¸°ìˆ í•˜ëŠ” ì˜ì—ì´ë‹¤. 실행 ì˜ì— ì ˆì— íŠ¹ì • ì‹œì (**AFTER** 나 **DEFERRED**)ì´ ì£¼ì–´ì§€ì§€ 않으면, 실행 ì˜ì—ì€ íŠ¸ë¦¬ê±° ì´ë²¤íŠ¸ì™€ ê°™ì€ ì‹œì ì—ì„œ 수행ëœë‹¤. 아래 목ë¡ì€ 트리거를 ì •ì˜í• ë•Œ ì‚¬ìš©í• ìˆ˜ 있는 실행 ì˜ì—ì˜ ëª©ë¡ì´ë‹¤. * **REJECT**: 트리거ì—ì„œ ì¡°ê±´ ì˜ì—ì´ ì°¸ì´ ì•„ë‹Œ 경우 트리거를 ë°œë™ì‹œí‚¨ ì—°ì‚°ì€ ê±°ì ˆë˜ê³ ë°ì´í„°ë² ì´ìŠ¤ì˜ ì˜ˆì „ ìƒíƒœë¥¼ 그대로 ìœ ì§€í•œë‹¤. ì—°ì‚°ì´ ìˆ˜í–‰ëœ í›„ì—는 ê±°ì ˆí• ìˆ˜ 없기 ë•Œë¬¸ì— **REJECT** 는 실행 ì‹œì ì´ **BEFORE** ì¼ ë•Œë§Œ 허용ëœë‹¤. ë”°ë¼ì„œ 실행 ì‹œì ì´ **AFTER** 나 **DERERRED** ì¸ ê²½ìš° **REJECT** 를 사용해서는 안 ëœë‹¤. * **INVALIDATE TRANSACTION**: 트리거를 부른 ì´ë²¤íŠ¸ ì—°ì‚°ì€ ìˆ˜í–‰ë˜ì§€ë§Œ, ì»¤ë°‹ì„ í¬í•¨í•˜ê³ 있는 트랜ìžì…˜ì€ 수행ë˜ì§€ ì•Šë„ë¡ í•œë‹¤. 트랜ìžì…˜ì´ ìœ íš¨í•˜ì§€ 않으면 반드시 **ROLLBACK** 문으로 취소시켜야 한다. ì´ëŸ¬í•œ ì‹¤í–‰ì€ ë°ì´í„°ë¥¼ 변경하는 ì´ë²¤íŠ¸ê°€ ë°œìƒí•œ í›„ì— ìœ íš¨í•˜ì§€ ì•Šì€ ë°ì´í„°ë¥¼ 가지는 것으로부터 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 보호하기 위해 사용ëœë‹¤. * **PRINT**: í„°ë¯¸ë„ í™”ë©´ì— í…스트 메시지로 트리거 활ë™ì„ 가시ì 으로 보여주기 ë•Œë¬¸ì— íŠ¸ë¦¬ê±°ì˜ ê°œë°œì´ë‚˜ 시험하는 ë„ì¤‘ì— ì‚¬ìš©ë 수 있다. ì´ë²¤íŠ¸ ì—°ì‚°ì˜ ê²°ê³¼ë¥¼ ê±°ì ˆí•˜ê±°ë‚˜ 무효화시키지는 않는다. * **INSERT**: í…Œì´ë¸”ì— í•˜ë‚˜ í˜¹ì€ ê·¸ ì´ìƒì˜ 새로운 ì¸ìŠ¤í„´ìŠ¤ë¥¼ 추가한다. * **UPDATE**: í…Œì´ë¸”ì— ìžˆëŠ” 하나 í˜¹ì€ ê·¸ ì´ìƒì˜ 칼럼 ê°’ì„ ë³€ê²½í•œë‹¤. * **DELETE**: í…Œì´ë¸”로부터 하나 í˜¹ì€ ê·¸ ì´ìƒì˜ ì¸ìŠ¤í„´ìŠ¤ë¥¼ ì œê±°í•œë‹¤. 다ìŒì€ 트리거 ìƒì„± ì‹œì— ì‹¤í–‰ì˜ì—ì˜ ì •ì˜ ë°©ë²•ì„ ë³´ì—¬ì£¼ëŠ” ì˜ˆì œì´ë‹¤. *medal_trig* 트리거는 실행 ì˜ì—ì— **REJECT** 를 ì§€ì •í•˜ì˜€ë‹¤. **REJECT** 는 실행 ì‹œì ì´ **BEFORE** ì¼ ë•Œë§Œ ì§€ì • 가능하다. .. code-block:: sql CREATE TRIGGER medal_trig BEFORE UPDATE ON participant IF new.gold < 0 OR new.silver < 0 OR new.bronze < 0 EXECUTE REJECT; .. note:: * **INSERT** ì´ë²¤íŠ¸ê°€ ì •ì˜ëœ íŠ¸ë¦¬ê±°ì˜ ì‹¤í–‰ ì˜ì—ì— **INSERT** 를 ì‚¬ìš©í• ë•ŒëŠ” 트리거가 무한 ë£¨í”„ì— ë¹ ì§ˆ 수 있으므로 주ì˜í•´ì•¼ 한다. * **UPDATE** ì´ë²¤íŠ¸ê°€ ì •ì˜ëœ 트리거가 ë¶„í• ëœ í…Œì´ë¸”ì—ì„œ ë™ìž‘하는 경우, ì •ì˜ëœ ë¶„í• ì´ ê¹¨ì§€ê±°ë‚˜ ì˜ë„하지 ì•Šì€ ì˜¤ë™ìž‘ì´ ë°œìƒí• 수 있으므로 주ì˜í•´ì•¼ 한다. ì´ë¥¼ 방지하기 위해 CUBRID는 트리거가 ë™ìž‘ì¤‘ì¸ ê²½ìš° ë¶„í• ë³€ê²½ì„ ì•¼ê¸°í•˜ëŠ” **UPDATE** ê°€ 실행ë˜ì§€ ì•Šë„ë¡ ì˜¤ë¥˜ 처리한다. **UPDATE** ì´ë²¤íŠ¸ê°€ ì •ì˜ëœ íŠ¸ë¦¬ê±°ì˜ ì‹¤í–‰ ì˜ì—ì— **UPDATE** 를 ì‚¬ìš©í• ë•ŒëŠ” 무한 ë£¨í”„ì— ë¹ ì§ˆ 수 있으므로 주ì˜í•´ì•¼ 한다. íŠ¸ë¦¬ê±°ì˜ ì»¤ë©˜íŠ¸ --------------- íŠ¸ë¦¬ì˜ ì»¤ë©˜íŠ¸ë¥¼ 다ìŒê³¼ ê°™ì´ ëª…ì‹œí• ìˆ˜ 있다. .. code-block:: sql CREATE TRIGGER trg_ab BEFORE UPDATE on abc(c) EXECUTE UPDATE cube_ab SET sumc = sumc + 1 COMMENT 'test trigger comment'; íŠ¸ë¦¬ê±°ì˜ ì»¤ë©˜íŠ¸ëŠ” ë‹¤ìŒ êµ¬ë¬¸ì—ì„œ 확ì¸í• 수 있다. .. code-block:: sql SELECT name, comment FROM db_trigger; SELECT trigger_name, comment FROM db_trig; ë˜ëŠ” CSQL ì¸í„°í”„리터ì—ì„œ 스키마를 ì¶œë ¥í•˜ëŠ” ;sc ëª…ë ¹ìœ¼ë¡œ íŠ¸ë¦¬ê±°ì˜ ì»¤ë©˜íŠ¸ë¥¼ 확ì¸í• 수 있다. .. code-block:: sql $ csql -u dba demodb csql> ;sc tbl 트리거 ì»¤ë©˜íŠ¸ì˜ ë³€ê²½ì€ ì•„ëž˜ì˜ **ALTER TRIGGER** ë¬¸ì„ ì°¸ê³ í•œë‹¤. .. _alter-trigger: ALTER TRIGGER ============= 트리거 ì •ì˜ì—ì„œ **STATUS** 와 **PRIORITY** ì˜µì…˜ì— ëŒ€í•´ **ALTER** êµ¬ë¬¸ì„ ì´ìš©í•˜ì—¬ ë³€ê²½í• ìˆ˜ 있다. 만약 íŠ¸ë¦¬ê±°ì˜ ë‹¤ë¥¸ ë¶€ë¶„ì— ëŒ€í•´ 변경(ì´ë²¤íŠ¸ ëŒ€ìƒ ë˜ëŠ” ì¡°ê±´ 표현ì‹)ì´ í•„ìš”í•˜ë©´, 트리거를 ì‚ì œí•œ 후 재ìƒì„±í•´ì•¼ 한다. :: ALTER TRIGGER [schema_name.]trigger_name <trigger_option> ; <trigger_option> ::= STATUS { ACTIVE | INACTIVE } | PRIORITY key * *schema_name*: íŠ¸ë¦¬ê±°ì˜ ìŠ¤í‚¤ë§ˆ ì´ë¦„ì„ ì§€ì •í•œë‹¤. ìƒëžµí•˜ë©´ 현재 ì„¸ì…˜ì˜ ìŠ¤í‚¤ë§ˆ ì´ë¦„ì„ ì‚¬ìš©í•œë‹¤. * *trigger_name*: ë³€ê²½í• íŠ¸ë¦¬ê±°ì˜ ì´ë¦„ì„ ì§€ì •í•œë‹¤. * **STATUS** { **ACTIVE** | **INACTIVE** }: íŠ¸ë¦¬ê±°ì˜ ìƒíƒœë¥¼ 변경한다. * **PRIORITY** *key*: ìš°ì„ ìˆœìœ„ë¥¼ 변경한다. 다ìŒì€ medal_trig 트리거를 ìƒì„±í•˜ê³ íŠ¸ë¦¬ê±°ì˜ ìƒíƒœë¥¼ **INACTIVE** ë¡œ, ìš°ì„ ìˆœìœ„ë¥¼ 0.7ë¡œ 변경하는 ì˜ˆì œì´ë‹¤. .. code-block:: sql CREATE TRIGGER medal_trig STATUS ACTIVE BEFORE UPDATE ON participant IF new.gold < 0 OR new.silver < 0 OR new.bronze < 0 EXECUTE REJECT; ALTER TRIGGER medal_trig STATUS INACTIVE; ALTER TRIGGER medal_trig PRIORITY 0.7; .. note:: * ê°™ì€ **ALTER TRIGGER** 문 ë‚´ì—서는 í•œ ê°œì˜ *trigger_option* 만 ê¸°ìˆ í• ìˆ˜ 있다. * 만약 í…Œì´ë¸” 트리거를 ë³€ê²½í•˜ë ¤ë©´, 해당 íŠ¸ë¦¬ê±°ì˜ ì†Œìœ ìžì´ê±°ë‚˜, 해당 트리거가 있는 í…Œì´ë¸”ì— ëŒ€í•´ **ALTER** ê¶Œí•œì´ ë¶€ì—¬ë˜ì–´ 있어야 한다. * ì‚¬ìš©ìž íŠ¸ë¦¬ê±°ë¥¼ 변경하기 위해서는 반드시 해당 íŠ¸ë¦¬ê±°ì˜ ì†Œìœ ìžì—¬ì•¼ 한다. *trigger_option* ì— ëŒ€í•œ ìžì„¸í•œ ë‚´ìš©ì€ :ref:`create-trigger` ì„ ì°¸ì¡°í•œë‹¤. **PRIORITY** 옵션과 ê°™ì´ ê¸°ìˆ í•˜ëŠ” key는 반드시 ìŒì´ ì•„ë‹Œ ë¶€ë™ ì†Œìˆ˜ì ê°’(non-negative floating point value)ì´ì–´ì•¼ 한다. 트리거 커멘트 ------------- 트리거 커멘트는 **ALTER TRIGGER** ë¬¸ì„ ì‹¤í–‰í•˜ì—¬ 다ìŒê³¼ ê°™ì´ ë³€ê²½í• ìˆ˜ 있다. :: ALTER TRIGGER [schema_name.]trigger_name [trigger_option] [COMMENT ‘comment_string’]; * *schema_name*: íŠ¸ë¦¬ê±°ì˜ ìŠ¤í‚¤ë§ˆ ì´ë¦„ì„ ì§€ì •í•œë‹¤. ìƒëžµí•˜ë©´ 현재 ì„¸ì…˜ì˜ ìŠ¤í‚¤ë§ˆ ì´ë¦„ì„ ì‚¬ìš©í•œë‹¤. * *trigger_name*: ë³€ê²½í• íŠ¸ë¦¬ê±°ì˜ ì´ë¦„ì„ ì§€ì •í•œë‹¤. * *comment_string*: íŠ¸ë¦¬ê±°ì˜ ì»¤ë©˜íŠ¸ë¥¼ ì§€ì •í•œë‹¤. íŠ¸ë¦¬ê±°ì˜ ì»¤ë©˜íŠ¸ë§Œ 변경하는 경우 트리거 옵션(trigger_option)ì„ ìƒëžµí• 수 있다. *trigger_option*\ì€ ìœ„ì˜ :ref:`alter-trigger` êµ¬ë¬¸ì„ ì°¸ê³ í•œë‹¤. .. code-block:: sql ALTER TRIGGER trg_ab COMMENT 'new trigger comment'; DROP TRIGGER ============ **DROP TRIGGER** êµ¬ë¬¸ì„ ì´ìš©í•˜ì—¬ 트리거를 ì‚ì œí•œë‹¤. :: DROP TRIGGER [schema_name.]trigger_name ; * *schema_name*: íŠ¸ë¦¬ê±°ì˜ ìŠ¤í‚¤ë§ˆ ì´ë¦„ì„ ì§€ì •í•œë‹¤. ìƒëžµí•˜ë©´ 현재 ì„¸ì…˜ì˜ ìŠ¤í‚¤ë§ˆ ì´ë¦„ì„ ì‚¬ìš©í•œë‹¤. * *trigger_name*: ì‚ì œí• íŠ¸ë¦¬ê±°ì˜ ì´ë¦„ì„ ì§€ì •í•œë‹¤. 다ìŒì€ medal_trig 트리거를 ì‚ì œí•˜ëŠ” ì˜ˆì œì´ë‹¤. .. code-block:: sql DROP TRIGGER medal_trig; .. note:: * 트리거가 ì‚¬ìš©ìž íŠ¸ë¦¬ê±°(즉 트리거 ì´ë²¤íŠ¸ê°€ **COMMIT** ì´ê±°ë‚˜ **ROLLBACK**)ì´ë©´, íŠ¸ë¦¬ê±°ì˜ ì†Œìœ ìžë§Œ ë³¼ 수 ìžˆê³ ì†Œìœ ìžë§Œ ì œê±°í• ìˆ˜ 있다. * í•œ ê°œì˜ **DROP TRIGGER** 문ì—서는 í•œ ê°œì˜ íŠ¸ë¦¬ê±°ë§Œ ì œê±°í• ìˆ˜ 있다.í…Œì´ë¸” 트리거는 트리거가 ì†í•´ 있는 í…Œì´ë¸”ì— ëŒ€í•´ **ALTER** ê¶Œí•œì´ ìžˆëŠ” 사용ìžì— ì˜í•´ ì œê±°ë 수 있다. RENAME TRIGGER ============== íŠ¸ë¦¬ê±°ì˜ ì´ë¦„ì€ **RENAME** êµ¬ë¬¸ì˜ **TRIGGER** 예약어를 ì´ìš©í•´ì„œ 변경한다. :: RENAME TRIGGER [schema_name.]old_trigger_name {AS | TO} [schema_name.]new_trigger_name ; * *schema_name*: íŠ¸ë¦¬ê±°ì˜ ìŠ¤í‚¤ë§ˆ ì´ë¦„ì„ ì§€ì •í•œë‹¤. ìƒëžµí•˜ë©´ 현재 ì„¸ì…˜ì˜ ìŠ¤í‚¤ë§ˆ ì´ë¦„ì„ ì‚¬ìš©í•œë‹¤. 현재 íŠ¸ë¦¬ê±°ì˜ ìŠ¤í‚¤ë§ˆì™€ ë³€ê²½í• íŠ¸ë¦¬ê±°ì˜ ìŠ¤í‚¤ë§ˆê°€ ë™ì¼í•´ì•¼ 한다. * *old_trigger_name*: íŠ¸ë¦¬ê±°ì˜ í˜„ìž¬ ì´ë¦„ì„ ìž…ë ¥í•œë‹¤. * *new_trigger_name*: ë³€ê²½í• íŠ¸ë¦¬ê±°ì˜ ì´ë¦„ì„ ì§€ì •í•œë‹¤. .. code-block:: sql RENAME TRIGGER medal_trigger AS medal_trig; .. note:: * 트리거 ì´ë¦„ì€ ì‚¬ìš©ìžê°€ ì†Œìœ í•˜ê³ ìžˆëŠ” 트리거 중ì—ì„œ ìœ ì¼í•´ì•¼ 한다. 하지만 ë°ì´í„°ë² ì´ìŠ¤ ë‚´ì˜ í…Œì´ë¸” ì´ë¦„ê³¼ 같거나 다른 ì†Œìœ ìžê°€ ì†Œìœ í•˜ê³ ìžˆëŠ” íŠ¸ë¦¬ê±°ì˜ ì´ë¦„과는 ê°™ì„ ìˆ˜ 있다. * 만약 í…Œì´ë¸” íŠ¸ë¦¬ê±°ì˜ ì´ë¦„ì„ ë³€ê²½í•˜ë ¤ë©´, íŠ¸ë¦¬ê±°ì˜ ì†Œìœ ìžì´ê±°ë‚˜, 해당 트리거가 있는 í…Œì´ë¸”ì— ëŒ€í•´ **ALTER** ê¶Œí•œì´ ë¶€ì—¬ë˜ì–´ 있어야 한다. ì‚¬ìš©ìž íŠ¸ë¦¬ê±°ëŠ” íŠ¸ë¦¬ê±°ì˜ ì†Œìœ ìžë§Œ ì´ë¦„ì„ ë³€ê²½í• ìˆ˜ 있다. ì§€ì—°ëœ íŠ¸ë¦¬ê±° ============= ì§€ì—°ëœ íŠ¸ë¦¬ê±° 실행ì˜ì—ê³¼ ì¡°ê±´ ì˜ì—ì€ ë‚˜ì¤‘ì— ì‹¤í–‰ë˜ê±°ë‚˜ 취소ë 수 있다. ì´ëŸ¬í•œ íŠ¸ë¦¬ê±°ë“¤ì€ ì´ë²¤íŠ¸ ì‹œì (event time)ì´ë‚˜ 실행 ì˜ì—(action) ì ˆì— **DEFERRED** 시간 ì˜µì…˜ì„ í¬í•¨í•˜ê³ 있다. **DEFERRED** ì˜µì…˜ì´ ì´ë²¤íŠ¸ ì‹œì ì— ê¸°ìˆ ë˜ê³ , 실행 ì˜ì— ì•žì— ì‹œê°„ì´ ìƒëžµë˜ì—ˆë‹¤ë©´, 실행 ì˜ì—ì€ ìžë™ìœ¼ë¡œ 지연ëœë‹¤. ì§€ì—°ëœ ì˜ì— 실행 ---------------- ì§€ì—°ëœ íŠ¸ë¦¬ê±°ì˜ ì¡°ê±´ ì˜ì—ì´ë‚˜ 실행 ì˜ì—ì„ ì¦‰ì‹œ 실행시킨다. :: EXECUTE DEFERRED TRIGGER <trigger_identifier> ; <trigger_identifier> ::= [schema_name.]trigger_name | ALL TRIGGERS * *schema_name*: íŠ¸ë¦¬ê±°ì˜ ìŠ¤í‚¤ë§ˆ ì´ë¦„ì„ ì§€ì •í•œë‹¤. ìƒëžµí•˜ë©´ 현재 ì„¸ì…˜ì˜ ìŠ¤í‚¤ë§ˆ ì´ë¦„ì„ ì‚¬ìš©í•œë‹¤. * *trigger_name*: íŠ¸ë¦¬ê±°ì˜ ì´ë¦„ì„ ì§€ì •í•˜ë©´ ì§€ì •ëœ íŠ¸ë¦¬ê±°ì˜ ì§€ì—°ëœ í™œë™ì´ 실행ëœë‹¤. * **ALL TRIGGERS**: 현재 ëª¨ë“ ì§€ì—°ëœ í™œë™ì´ 실행ëœë‹¤. ì§€ì—°ëœ ì˜ì— 취소 ---------------- ì§€ì—°ëœ íŠ¸ë¦¬ê±°ì˜ ì¡°ê±´ ì˜ì—ê³¼ 실행 ì˜ì—ì„ ì·¨ì†Œí•œë‹¤. :: DROP DEFERRED TRIGGER <trigger_identifier> ; <trigger_identifier> ::= [schema_name.]trigger_name | ALL TRIGGERS * *schema_name*: íŠ¸ë¦¬ê±°ì˜ ìŠ¤í‚¤ë§ˆ ì´ë¦„ì„ ì§€ì •í•œë‹¤. ìƒëžµí•˜ë©´ 현재 ì„¸ì…˜ì˜ ìŠ¤í‚¤ë§ˆ ì´ë¦„ì„ ì‚¬ìš©í•œë‹¤. * *trigger_name*: íŠ¸ë¦¬ê±°ì˜ ì´ë¦„ì„ ì§€ì •í•˜ë©´ ì§€ì •ëœ íŠ¸ë¦¬ê±°ì˜ ì§€ì—°ëœ í™œë™ì´ 취소ëœë‹¤. * **ALL TRIGGERS**: 현재 ëª¨ë“ ì§€ì—°ëœ í™œë™ì´ 취소ëœë‹¤. 트리거 권한 부여 ---------------- íŠ¸ë¦¬ê±°ì— ëŒ€í•œ ê¶Œí•œì€ ëª…ì‹œì 으로 부여ë˜ì§€ 않는다. íŠ¸ë¦¬ê±°ì˜ ì •ì˜ì— ê¸°ìˆ ëœ ì´ë²¤íŠ¸ ëŒ€ìƒ í…Œì´ë¸”ì— ê¶Œí•œì´ ë¶€ì—¬ë˜ì—ˆì„ ë•Œ 사용ìžëŠ” í…Œì´ë¸” íŠ¸ë¦¬ê±°ì— ëŒ€í•œ ê¶Œí•œì„ ìžë™ì 으로 íšë“한다. 다시 ë§í•˜ìžë©´, í…Œì´ë¸” 대ìƒ(**INSERT**, **UPDATE** 등)ì„ ê°€ì§€ëŠ” 트리거는 해당 í…Œì´ë¸”ì— ì ì ˆí•œ ê¶Œí•œì„ ê°€ì§€ëŠ” ëª¨ë“ ì‚¬ìš©ìžì—게 ë³´ì¸ë‹¤. ì‚¬ìš©ìž íŠ¸ë¦¬ê±°(**COMMIT** ê³¼ **ROLLBACK**)는 트리거를 ì •ì˜í•œ 사용ìžë§Œ ë³¼ 수 있다. íŠ¸ë¦¬ê±°ì˜ ì†Œìœ ìžì´ë©´ ëª¨ë“ ê¶Œí•œì€ ìžë™ì 으로 부여ëœë‹¤. .. note:: * í…Œì´ë¸” 트리거를 ì •ì˜í•˜ê¸° 위해서는 ê´€ë ¨ëœ í…Œì´ë¸”ì— **ALTER** ê¶Œí•œì´ ë°˜ë“œì‹œ 있어야 한다. * ì‚¬ìš©ìž íŠ¸ë¦¬ê±°ë¥¼ ì •ì˜í•˜ê¸° 위해서는 ìœ íš¨í•œ 사용ìžë¥¼ ì´ìš©í•˜ì—¬ ë°ì´í„°ë² ì´ìŠ¤ì— ì ‘ê·¼í•˜ëŠ” ê²ƒì´ í•„ìš”í•˜ë‹¤. REPLACE와 INSERT ... ON DUPLICATE KEY UPDATEì—ì„œì˜ íŠ¸ë¦¬ê±° ========================================================= CUBRIDì—서는 **REPLACE** 문과 **INSERT ... ON DUPLICATE KEY UPDATE** 문 실행 ì‹œ 내부ì 으로 **DELETE**, **UPDATE**, **INSERT** ìž‘ì—…ì´ ë°œìƒí•˜ë©´ì„œ 해당 트리거가 실행ëœë‹¤. ë‹¤ìŒ í‘œëŠ” **REPLACE** í˜¹ì€ **INSERT ... ON DUPLICATE KEY UPDATE** ë¬¸ì´ ìˆ˜í–‰ë ë•Œ ë°œìƒí•˜ëŠ” ì´ë²¤íŠ¸ì— ë”°ë¼ CUBRIDì—ì„œ 트리거가 ì–´ë–¤ 순서로 ë™ìž‘하는지를 나타낸다. **REPLACE** 문과 **INSERT ... ON DUPLICATE KEY UPDATE** 문 ëª¨ë‘ ìƒì†ë°›ì€ í´ëž˜ìŠ¤(í…Œì´ë¸”)ì—서는 트리거가 ë™ìž‘하지 않는다. **REPLACE와 INSERT ... ON DUPLICATE KEY UPDATE 문ì—ì„œ íŠ¸ë¦¬ê±°ì˜ ë™ìž‘ 순서** +--------------------------------------------+------------------+ | ì´ë²¤íŠ¸ | 트리거 ë™ìž‘ 순서 | +============================================+==================+ | REPLACE | BEFORE DELETE > | | ë ˆì½”ë“œê°€ ì‚ì œë˜ê³ 삽입ë ë•Œ | AFTER DELETE > | | | BEFORE INSERT > | | | AFTER INSERT | +--------------------------------------------+------------------+ | INSERT ... ON DUPLICATE KEY UPDATE | BEFORE UPDATE > | | ë ˆì½”ë“œê°€ ì—…ë°ì´íŠ¸ë ë•Œ | AFTER UPDATE | +--------------------------------------------+------------------+ | REPLACE, INSERT ... ON DUPLCATE KEY UPDATE | BEFORE INSERT > | | ë ˆì½”ë“œê°€ 삽입만 ë ë•Œ | AFTER INSERT | +--------------------------------------------+------------------+ 다ìŒì€ *with_trigger* í…Œì´ë¸”ì— **INSERT ... ON DUPLICATE KEY UPDATE** 와 **RELPACE** 를 수행하면 트리거가 ë™ìž‘하여 *trigger_actions* í…Œì´ë¸”ì— ë ˆì½”ë“œë¥¼ 삽입하는 ì˜ˆì œì´ë‹¤. .. code-block:: sql CREATE TABLE with_trigger (id INT UNIQUE); INSERT INTO with_trigger VALUES (11); CREATE TABLE trigger_actions (val INT); CREATE TRIGGER trig_1 BEFORE INSERT ON with_trigger EXECUTE INSERT INTO trigger_actions VALUES (1); CREATE TRIGGER trig_2 BEFORE UPDATE ON with_trigger EXECUTE INSERT INTO trigger_actions VALUES (2); CREATE TRIGGER trig_3 BEFORE DELETE ON with_trigger EXECUTE INSERT INTO trigger_actions VALUES (3); INSERT INTO with_trigger VALUES (11) ON DUPLICATE KEY UPDATE id=22; SELECT * FROM trigger_actions; :: va ============== 2 .. code-block:: sql REPLACE INTO with_trigger VALUES (22); SELECT * FROM trigger_actions; :: va ============== 2 3 1 트리거 디버깅 ============= 트리거를 ì •ì˜í•œ 후ì—는 트리거가 ì˜ë„í•œ 대로 ë™ìž‘하는지 검사하는 ê²ƒì´ ì¢‹ë‹¤. 종종 트리거가 ê¸°ëŒ€í–ˆë˜ ê²ƒë³´ë‹¤ ì²˜ë¦¬í•˜ëŠ”ë° ì˜¤ëžœ ì‹œê°„ì´ ê±¸ë¦¬ëŠ” 경우가 있다. ì´ëŠ” ì‹œìŠ¤í…œì— ë„ˆë¬´ ë§Žì€ ì˜¤ë²„í—¤ë“œë¥¼ 주거나, 재귀ì ë£¨í”„ì— ë¹ ì¡Œë‹¤ëŠ” 뜻ì´ë‹¤. ì´ ì ˆì—서는 트리거를 디버그하는 몇 가지 ë°©ë²•ì„ ì„¤ëª…í•œë‹¤. 다ìŒì€ 호출ë˜ë©´ 재귀ì 으로 ë£¨í”„ì— ë¹ ì§€ë„ë¡ ì •ì˜í•œ 트리거ì´ë‹¤. *loop_trg* 트리거는 목ì ì´ ë‹¤ì†Œ ì¸ìœ„ì ì´ì§€ë§Œ 트리거를 디버그하기 위한 ì˜ˆì œë¡œ 사용ë 수 있다. .. code-block:: sql CREATE TRIGGER loop_tgr BEFORE UPDATE ON participant(gold) IF new.gold > 0 EXECUTE UPDATE participant SET gold = new.gold - 1 WHERE nation_code = obj.nation_code AND host_year = obj.host_year; 트리거 실행 로그 보기 --------------------- **SET TRIGGER TRACE** ë¬¸ì„ ì´ìš©í•˜ì—¬ 터미ë„ì—ì„œ íŠ¸ë¦¬ê±°ì˜ ì‹¤í–‰ 로그를 ë³¼ 수 있다. :: SET TRIGGER TRACE <switch> ; <switch> ::= ON | OFF * **ON**: **TRACE** ê°€ ìž‘ë™ë˜ë©° **OFF** 하거나 현재 ë°ì´í„°ë² ì´ìŠ¤ ì„¸ì…˜ì„ ì¢…ë£Œí• ë•Œê¹Œì§€ ê³„ì† ìœ ì§€ëœë‹¤. * **OFF**: **TRACE** ì˜ ìž‘ë™ì„ 멈춘다. ë‹¤ìŒ ì˜ˆì œëŠ” íŠ¸ë¦¬ê±°ì˜ ì‹¤í–‰ 로그를 보기 위해 **TRACE** 를 ìž‘ë™ì‹œí‚¤ê³ *loop_trg* 트리거를 ìž‘ë™ì‹œí‚¤ëŠ” ì˜ˆì œì´ë‹¤. 트리거가 호출ë ë•Œ ìˆ˜í–‰ëœ ê°ê°ì˜ ì¡°ê±´ ì˜ì—ê³¼ 실행 ì˜ì—ì— ëŒ€í•œ 추ì ì„ ì‹ë³„하기 위한 메시지가 터미ë„ì— ë‚˜íƒ€ë‚œë‹¤. *loop_trg* 트리거는 *gold* ê°’ì´ 0ì´ ë 때까지 실행ë˜ë¯€ë¡œ ì˜ˆì œì—서는 ì•„ëž˜ì˜ ë©”ì„¸ì§€ê°€ 15번 나타난다. .. code-block:: sql SET TRIGGER TRACE ON; UPDATE participant SET gold = 15 WHERE nation_code = 'KOR' AND host_year = 1988; :: TRACE: Evaluating condition for trigger "loop". TRACE: Executing action for trigger "loop". ì¤‘ì²©ëœ íŠ¸ë¦¬ê±° ì œí•œ ------------------ **SET TRIGGER** ë¬¸ì˜ **MAXIMUM DEPTH** 키워드를 ì´ìš©í•˜ì—¬ 단계ì 으로 ë°œë™ë˜ëŠ” 트리거 수를 ì œí•œí• ìˆ˜ 있다. ì´ë¥¼ ì´ìš©í•˜ë©´ 재귀ì 으로 호출ë˜ëŠ” 트리거가 ë¬´í•œë£¨í”„ì— ë¹ ì§€ëŠ” ê²ƒì„ ë§‰ì„ ìˆ˜ 있다. :: SET TRIGGER [ MAXIMUM ] DEPTH count ; * *count*: ì–‘ì˜ ì •ìˆ˜ê°’ìœ¼ë¡œ 트리거가 다른 트리거나 ìžì‹ ì„ ìž¬ê·€ì 으로 ë°œë™í• 수 있는 횟수를 ì§€ì •í•œë‹¤. íŠ¸ë¦¬ê±°ì˜ ìˆ˜ê°€ 최대 깊ì´ì— ë„달하면 ë°ì´í„°ë² ì´ìŠ¤ ìš”ì²ì€ 중단ë˜ê³ 트랜ìžì…˜ì€ ìœ íš¨í•˜ì§€ ì•Šì€ ê²ƒì²˜ëŸ¼ 표시ëœë‹¤. ì„¤ì •ëœ **DEPTH** 는 현재 ì„¸ì…˜ì„ ì œì™¸í•œ 나머지 ëª¨ë“ íŠ¸ë¦¬ê±°ì— ì ìš©ëœë‹¤. ìµœëŒ€ê°’ì€ 32ì´ë‹¤. 다ìŒì€ 재귀ì 트리거 í˜¸ì¶œì˜ ìµœëŒ€ ê°’ì„ 10으로 ì„¤ì •í•˜ëŠ” ì˜ˆì œì´ë‹¤. ì´ëŠ” ì´í›„ì— ë°œë™í•˜ëŠ” ëª¨ë“ íŠ¸ë¦¬ê±°ì— ì ìš©ëœë‹¤. ì´ ì˜ˆì œì—ì„œ *gold* ì¹¼ëŸ¼ì— ëŒ€í•œ ê°’ì€ 15ë¡œ ê°±ì‹ ë˜ì–´ 트리거는 ì´ 16번 ë¶ˆë ¤ì§€ê²Œ ëœë‹¤. ì´ëŠ” 현재 ì„¤ì •ëœ ìµœëŒ€ 깊ì´ë¥¼ 초과하게 ë˜ê³ 아래와 ê°™ì€ ì—러 메시지가 ë°œìƒí•œë‹¤. .. code-block:: sql SET TRIGGER MAXIMUM DEPTH 10; UPDATE participant SET gold = 15 WHERE nation_code = 'KOR' AND host_year = 1988; :: ERROR: Maximum trigger depth 10 exceeded at trigger "loop_tgr". 트리거를 ì´ìš©í•œ ì‘ìš© ==================== 여기ì—서는 ë°ëª¨ ë°ì´í„°ë² ì´ìŠ¤ì— 있는 트리거 ì •ì˜ì— 대해 알아본다. *demodb* ë°ì´í„°ë² ì´ìŠ¤ì— ìƒì„±ë˜ì–´ 있는 트리거는 그리 복잡하지는 않지만 CUBRIDì—ì„œ ì‚¬ìš©í• ìˆ˜ 있는 ëŒ€ë¶€ë¶„ì˜ ê¸°ëŠ¥ì„ í™œìš©í•œë‹¤. ì´ëŸ¬í•œ 트리거를 í…ŒìŠ¤íŠ¸í• ë•Œ, *demodb* ë°ì´í„°ë² ì´ìŠ¤ì˜ ì›í˜•ì„ ìœ ì§€í•˜ê³ ì‹¶ë‹¤ë©´ ë°ì´í„°ì— ë³€ê²½ì´ ë°œìƒí•œ 후 ë¡¤ë°±ì„ ìˆ˜í–‰í•´ì•¼ 한다. ì‚¬ìš©ìž ë°ì´í„°ë² ì´ìŠ¤ì— ì§ì ‘ ìƒì„±í•œ 트리거는 사용ìžê°€ ë§Œë“ ì‘ìš© 프로그램만í¼ì´ë‚˜ ê°•ë ¥í• ìˆ˜ 있다. *participant* í…Œì´ë¸”ì— ë§Œë“¤ì–´ì§„ 아래 트리거는 ì œì‹œëœ ê°’ì´ 0보다 ìž‘ì„ ë•Œ 메달 칼럼(*gold*, *silver*, *bronze*)ì— ëŒ€í•œ ì—…ë°ì´íŠ¸ë¥¼ ê±°ì ˆí•œë‹¤. íŠ¸ë¦¬ê±°ì˜ ì¡°ê±´ì— ìƒê´€ëª… newê°€ 사용ë˜ì—ˆê¸° ë•Œë¬¸ì— ì‹œìž‘ ì‹œì (evaluation time)ì€ ë°˜ë“œì‹œ **BEFORE** ê°€ ë˜ì–´ì•¼ 한다. ë¹„ë¡ ê¸°ìˆ í•˜ì§€ëŠ” 않았지만, ì´ íŠ¸ë¦¬ê±°ì—ì„œ 실행 ì‹œì (action time) ë˜í•œ **BEFORE** ì´ë‹¤. .. code-block:: sql CREATE TRIGGER medal_trigger BEFORE UPDATE ON participant IF new.gold < 0 OR new.silver < 0 OR new.bronze < 0 EXECUTE REJECT; êµê°€ 코드가 'BLA'ì¸ ë‚˜ë¼ì˜ 금메달(*gold*) 수를 ì—…ë°ì´íŠ¸ í• ë•Œ, *medal_trigger* 트리거가 ë°œë™í•œë‹¤. 금메달 수가 ìŒìˆ˜ì¸ 경우를 허용하지 ì•Šë„ë¡ íŠ¸ë¦¬ê±°ë¥¼ ìƒì„±í•˜ì˜€ìœ¼ë¯€ë¡œ, ì—…ë°ì´íŠ¸ë¥¼ 허용하지 않는다. .. code-block:: sql UPDATE participant SET gold = -10 WHERE nation_code = 'BLA'; 아래 트리거는 ìœ„ì˜ ì˜ˆì œì™€ ê°™ì€ ì¡°ê±´ì¸ë°, **STATUS ACTIVE** ê°€ ì¶”ê°€ëœ ê²½ìš°ì´ë‹¤. **STATUS** ë¬¸ì´ ìƒëžµë 경우 ê¸°ë³¸ê°’ì€ **ACTIVE** ì´ë©°, **ALTER TRIGGER** ë¬¸ì— ì˜í•´ **STATUS** 를 **INACTIVE** ë¡œ ë³€ê²½í• ìˆ˜ 있다. **STATUS** ì˜ ê°’ì— ë”°ë¼ íŠ¸ë¦¬ê±°ì˜ ì‹¤í–‰ 여부를 ì§€ì •í• ìˆ˜ 있다. .. code-block:: sql CREATE TRIGGER medal_trig STATUS ACTIVE BEFORE UPDATE ON participant IF new.gold < 0 OR new.silver < 0 OR new.bronze < 0 EXECUTE REJECT; ALTER TRIGGER medal_trig STATUS INACTIVE; ë‹¤ìŒ íŠ¸ë¦¬ê±°ëŠ” 트랜ìžì…˜ì´ 커밋ë˜ì—ˆì„ ë•Œ 어떻게 무결성 ì œì•½ ì¡°ê±´ì„ ê°•ì œì 으로 수행하는지 ë³´ì—¬ 준다. í•˜ë‚˜ì˜ íŠ¸ë¦¬ê±°ê°€ 여러 í…Œì´ë¸”ì— ëŒ€í•´ ì§€ì • ì¡°ê±´ì„ ë„£ì„ ìˆ˜ 있다는 ì ì´ ì•žì˜ ì˜ˆì œì™€ 다르다. .. code-block:: sql CREATE TRIGGER check_null_first BEFORE COMMIT IF 0 < (SELECT count(*) FROM athlete WHERE gender IS NULL) OR 0 < (SELECT count(*) FROM game WHERE nation_code IS NULL) EXECUTE REJECT; ë‹¤ìŒ íŠ¸ë¦¬ê±°ëŠ” *record* í…Œì´ë¸”ì— ëŒ€í•´ì„œ 트랜ìžì…˜ì´ 커밋ë 때까지 ì—…ë°ì´íŠ¸ 무결성 ì œì•½ì¡°ê±´ 검사를 지연시킨다. **DEFERRED** 키워드가 ì´ë²¤íŠ¸ ì‹œì 으로 주어졌기 ë•Œë¬¸ì— ì—…ë°ì´íŠ¸ 실행 ì‹œì ì— ì¦‰ì‹œ 트리거가 실행ë˜ì§€ëŠ” 않는다. .. code-block:: sql CREATE TRIGGER deferred_check_on_record DEFERRED UPDATE ON record IF obj.score = '100' EXECUTE INVALIDATE TRANSACTION; *record* í…Œì´ë¸”ì—ì„œ ì—…ë°ì´íŠ¸ê°€ 완료ë˜ì—ˆì„ ë•Œ, 해당 ì—…ë°ì´íŠ¸ëŠ” 현재 트랜ìžì…˜ì˜ 마지막(커밋ì´ë‚˜ ë¡¤ë°±í• ë•Œ)ì— í™•ì¸í•˜ê²Œ ëœë‹¤. ìƒê´€ëª… **old** 는 **DEFERRED UPDATE** 를 사용하는 íŠ¸ë¦¬ê±°ì˜ ì¡°ê±´ ì ˆì— ì‚¬ìš©í• ìˆ˜ 없다. ë”°ë¼ì„œ 아래와 ê°™ì€ íŠ¸ë¦¬ê±°ëŠ” ìƒì„±í• 수 없다. .. code-block:: sql CREATE TABLE foo (n int); CREATE TRIGGER foo_trigger DEFERRED UPDATE ON foo IF old.n = 100 EXECUTE PRINT 'foo_trigger'; 위와 ê°™ì´ íŠ¸ë¦¬ê±°ë¥¼ ìƒì„±í•˜ë ¤ê³ 하면 다ìŒê³¼ ê°™ì€ ì—러 메시지를 ë³´ì—¬ì£¼ê³ , 실패한다. :: ERROR: Error compiling condition for 'foo_trigger' : old.n is not defined. ìƒê´€ëª… **old** 는 íŠ¸ë¦¬ê±°ì˜ ì¡°ê±´ ì‹œê°„ì´ **AFTER** ì¼ ë•Œì—만 사용ë 수 있다.