
시스템 카탈로그 테이블을 이용하여 트리거 백업하기
조회 수 3650 추천 수 0 2010.08.11 20:47:09시스템 카탈로그 테이블을 이용하여 트리거 백업하기
소개: db_trigger 시스템 카탈로그 테이블을 이용하여 이미 생성되어 있는 트리거의 생성 스크립트를 만드는 방법을 설명한다.
적용 대상: CUBRID2008
DB에 존재하는 Object들의 정보는 시스템 카탈로그 테이블을 적절히 이용하면 확인할 수 있다. 트리거도 마찬가지로 트리거에 대한 정보는 db_trigger라는 시스템 카탈로그 테이블을 이용하면 확인할 수 있다.
먼저 트리거 정의 구문을 살펴보면 아래와 같다.
CREATE TRIGGER trigger_name
event_time event_typeevent_target
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 관련 트리거 제외
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을 변경하기 위한 구문이다.