시스템 카탈로그 테이블을 이용하여 트리거 백업하기

소개: db_trigger 시스템 카탈로그 테이블을 이용하여 이미 생성되어 있는 트리거의 생성 스크립트를 만드는 방법을 설명한다.

적용 대상: CUBRID2008

시스템 카탈로그 테이블 db_trigger

DB에 존재하는 Object들의 정보는 시스템 카탈로그 테이블을 적절히 이용하면 확인할 수 있다. 트리거도 마찬가지로 트리거에 대한 정보는 db_trigger라는 시스템 카탈로그 테이블을 이용하면 확인할 수 있다.

먼저 트리거 정의 구문을 살펴보면 아래와 같다.

CREATE TRIGGER trigger_name

INACTIVE }

PRIORITYkey

event_time event_typeevent_target

IFcondition

EXECUTE DEFERRED action ;

 

event_time:

 - BEFORE

 - AFTER

 - DEFERRED

 

event_type:

 - INSERT

 - STATEMENT INSERT

 - UPDATE

 - STATEMENT UPDATE

 - DELETE

 - STATEMENT DELETE

 - ROLLBACK

 - COMMIT

 

event_target:

 - ON table_name

 - ON table_name (column_name)

 

condition:

 - expression

 

action:

 - REJECT  

 - INVALIDATE TRANSACTION

 - PRINT message_string

 - INSERT statement

 - UPDATE statement

 - DELETE statement

트리거 구문에 대한 자세한 내용은 CUBRID 매뉴얼 > CUBRID SQL 설명서 > 트리거 > CREATE TRIGGER 부분을 참고하기 바란다.

다음으로 트리거 구문과 db_trigger 시스템 카탈로그 테이블이 서로 어떤 관계가 있는지를 살펴보면 아래와 같다.

트리거 구문

db_trigger

비고

trigger_name

name

 

status

status

1 inactive, 2 active

PRIORITYkey

priority

 

event_time

condition_type NULL 인 경우 action_time이 적용.

1 before, 2 after, 3 deferred

condition_type NULL이 아닌 경우 condition_time이 적용.

NULL after, 1 before, 2 after, 3 deferred

event_type

event

0 update, 1 statement update, 2 delete, 3 statement delete, 4 insert, 5 statement insert, 8 commit, 9 rollback

event_target

table_name

db_trig 시스템 카탈로그 테이블의 target_class_name.

Select target_class_name from db_trig where trigger_name=name subquery 로 확인

column_name

target_attribute

 

IFcondition

condition

 

EXECUTE DEFERRED

condition_type NULL이 아닌 경우만 action_time이 적용.

2 after, 3 deferred

action

action_type

1 action_definition이 적용, 2 reject, 3 invalidate transaction, 4 print action_definition

위 트리거 구문과 db_trigger의 관계를 토대로 트리거 생성 구문을 만드는 스크립트는 아래와 같다.

#!/bin/bash

echo "create trigger sql"

DB_NAME=demodb

res_count=`csql -u dba ${DB_NAME} -c "select count(*) from db_trigger where name <> 'glo_delete_contents'" |tail -n 2 | awk '{ print $1 }'`

# 트리거의 개수 확인. DBMS 내부적으로 사용되는 glo 관련 트리거 제외

if $res_count != 0

  then

    res_count=`expr $res_count + 1`

    csql -u dba ${DB_NAME} -c "select 'create trigger '||name||         /* 트리거 이름 */ \

        ' status '|| decode(status,1,'inactive',2,'active') ||  /* 트리거 status */ \

        ' priority '||cast(priority as numeric(10,5)) ||' ' ||  /* 트리거 priority */ \

        decode(condition_type,null,decode(action_time,1,'before ',2,'after ',3,'deferred '), decode(condition_time, null, 'after', 1, 'before', 2, 'after', 3, 'deferred')) ||' '||     /* 트리거 event time */ \

        decode(event,0,'update',1, 'statement update',2,'delete',3,'statement delete',4,'insert',5,'statement insert',8,'commit',9,'rollback')||        /* 트리거 event type */ \

        ' on \"'||(select target_class_name from db_trig where trigger_name=name)|| '\"' ||   /* 트리거 event target */ \

        decode(target_attribute,null,'',' (\"'||target_attribute||'\")') ||     /* 트리거 event target 컬럼 */ \

        decode(condition,null,'',' if '||condition) ||  /* 트리거 IF condition */ \

        ' execute '|| decode(condition_type,null,'',decode(action_time,1,'',2,'after ',3,'deferred '))|| decode(action_type,1,action_definition,2,'reject',3,'invalidate transaction',4,'print ''' || action_definition||'''')||';'||   /* 트리거 execute action time action */ \

        'call change_trigger_owner(''' || name ||''', ''' ||  (select name from db_user where db_user=owner) || ''') on class db_root;'         /* 트리거 owner 변경 */ \

        from db_trigger where name <> 'glo_delete_contents'" | tail -n $res_count | sed -e "s|'create|create|g" | sed -e "s|;'|;|g" > ./create_trig_${DB_NAME}.sql

  fi

echo "end"

위 스크립트를 실행한 결과를 확인하기 위해 아래와 같이 트리거를 생성한다.

CREATE TRIGGER medal_trigger

BEFORE UPDATE ON participant

IF new.gold < 0 OR new.silver < 0 OR new.bronze < 0

EXECUTE REJECT;

위 스크립트를 실행하면 create_trig_demodb.sql이라는 파일이 생성되는데 파일을 열어 보면 아래와 같이 트리거 생성 구문을 확인할 수 있다.

create trigger medal_trigger status active priority 0.00000 before update on "participant" if new.gold<0 or new.silver<0 or new.bronze<0 execute reject;call change_trigger_owner('medal_trigger', 'PUBLIC') on class db_root;

결과에 트리거 생성과 관련이 없는 call change_trigger_owner라는 구문이 포함되어 있는데 이는 트리거의 owner DBA가 아닌 경우에 owner을 변경하기 위한 구문이다.