오라클이나 ms-sql에서 트리거가 작동되는 시점을 설정하는 after나 before같은 설정은 sybase에서 어떻게 하나요?
sybase는 before나 after이 없습니다.
inserted나 deleted의 data를 처리 해야 합니다.
앞에 분이 말씀하신데로 sybase 에는 before 나 after 설정이 없습니다. trigger 관련 내용이 필요하신가 해서 올려 드립니다.
Trigger
Syntax
4 트리거는 테이블에 직접 바인드 된 객체이다
4 테이블에 데이터 변경(insert,update,delete)을 시도할 때 자동적으로 실행된다
create trigger [owner.]trigger_name
on [owner.]table_name
for {insert, update, delete}
as SQL_statements
Or, using the if update clause:
for {insert, update}
as
[if update (column_name)
[{and | or} update (column_name)]...]
SQL_statements
[{and | or} update (column_name)]...
SQL_statements]...
Trigger는 언제 실행되는가?
4 trigger를 기동시킨 sql문장과 1 transaction이다
순서를 정한다면, 기동시킨 sql문장이 실행되고, 실행결과로 inserted 또는 deleted라는 특별한 view 생성되고나서 수행된다고 봐도 좋다
잠시동안 Trigger를 중지할 수 있는가?
4 ASE 12.0 이후에서는 alter table 명령문에서 trigger를 enable/disable시킬 수 있다
1> alter table titles disable trigger deltitle
2> go
Disabling trigger 'deltitle'.
1> alter table titles enable trigger deltitle
Enabling trigger 'deltitle'
한 column의 변화만을 대상으로 하는 trigger도 가능한가?
4 if update(column명)을 사용하면 가능하다
여기서 변화라는 것은 값의 변화를 의미하는 것이 아니라 해당 column의 update수행여부를 말하는 것입니다. 만약 해당 column의 값의 변화를 check하고 싶다면 deleted,inserted table의 해당 column을 비교해서 이용해야 합니다
1>create trigger TEST_TAB_trg on TEST_TAB for insert,update,delete
2>as
3> if update(COL1)
4> begin
5> select "Updated !!"
6> end
7>return
8>go
1> insert into TEST_TAB values (1)
----------
Updated !!
(1 row affected)
1> update TEST_TAB set COL1 = 1
delete에서는 기동 되지 않는다
1> delete TEST_TAB
foreign key constraint가 걸린 경우, trigger통한 cascade delete는?
4 error가 생긴다. constraint도 trigger로 바꿔 구현해야 한다
parent_tab의 primary key를 child_tab에서 foreign key 로 constraint를 선언한 경우에
parent tab 의 cascade delete를 수행하면 error 가 발생한다
이럴 경우는 parent_tab에 delete trigger에 cascade trigger를 만들고, child_tab에 insert/update trigger를 만들어 foreign key constraint를 대신해야 한다
parent_tab 의 primary key는 p_col1, p_col2 이다
child_tab의 c_col1,c_col2는 parent_tab 의 p_col1, p_col2에 대응한다
create table parent_tab (p_col1 int,p_col2 int)
create table chlid_tab (c_col1 int,c_col2 int,c_col3 int)
child_tab의 insert / update trigger에서 parent_tab에 없는 내용이면 i/u못하게 한다
create trigger child_tab_iu on child_tab for insert,update as
declare @i_count int,@d_count int
if not exists ( select 1 from parent_tab p,inserted i
where p.p_col1 = i.c_col1
and p.p_col2 = i.c_col2 )
begin
print "not in parent table"
rollback tran
end
return
parent_tab 의 delete trigger에는 cascade delete기능을 넣는다
create trigger parent_tab_d on parent_tab for delete as
delete child_tab
from child_tab, deleted d
where c_col1 = d.p_col1
and c_col2 = d.p_col2
child_tab insert는 항상 parent_tab에 있어야 한다
1> select * from child_tab
c_col1 c_col2 c_col3
----------- ----------- -----------
1 1 1
2 2 2
(2 rows affected)
1> select * from parent_tab
p_col1 p_col2
----------- -----------
1 1
3 3
4 4
(4 rows affected)
parent_tab에 7은 없다. insert 안된다
1> insert into child_tab values (7,7,7)
not in parent table
parent_tab에 있는 delete하면 child_tab의 내용을 삭제하는 cascade delete를 점검한다
1> delete parent_tab where p_col1 = 1
(1 rows affected)
2 2
Trigger(statement level) 를 row level로 바꾸려면?
4 cursor를 이용한다
1> create trigger del_TEST_TAB
2> on TEST_TAB for delete
3> as
4>
5> declare @a int,@b int,@c int
6>
7> declare XX cursor for
8> select * from deleted
9>
10> open XX
11>
12> fetch XX into @a,@b,@c
13>
14> while @@sqlstatus = 0
15> begin
16> insert D_TEST_TAB values (@a,@b,@c)
17> fetch XX into @a,@b,@c
18> end
19>
20> close XX
21> deallocate cursor XX
22>
23> return
24> go