数据同步之各站点同步表触发器创建,数据同步触发器
在前一个博客中提到了在数据同步的时候,在各站点需要建立各操作表的触发器,在执行增删改的时候,触发器的任务是将其中操作的sql语句拼接成字符串,并保存在表synchro_tb_operate_log中,如果触发器执行出现异常,则将其异常信息保存在另一个表中:SYNCHRO_DATA_EXCEP_LOG,其中
synchro_tb_operate_log字段信息:主键ID、拼接的sql语句(其中包含主键ID和地区代码)、是否完成同步(默认为0未完成)、创建时间
SYNCHRO_DATA_EXCEP_LOG字段信息:主键ID、触发器异常名称、触发器异常信息、触发器异常出现的时间
下面是创建item_rec代码,也可以让我们来学习一下创建触发器相关的语法和知识:
create or replace TRIGGER "ADMIN"."TRIGGER_ITEM_REC" after insert or update or delete on ITEM_REC FOR EACH ROW /** HEAD * @name 项目记录表触发器 * @description 变更事件,形成ddl语句插入同步表中 * @version 1.0.0 * @author Tang * @create-date 2014-07-01 */ declare v_sql nvarchar2(3000); --临时存放sql v_zdcode varchar2(30):='08052'; --站点代码 v_exception varchar2(500); begin v_sql := null; case when inserting then--插入数据 v_sql := 'insert into ITEM_REC('|| 'ID,PROTEAMNAME,PY,PROID,'|| 'JCTYPE,WORKFLAG,ZXFLAG,JWDCODE)'|| 'values('''|| :new.ID||''','''||replace(:new.PROTEAMNAME,'''','')||''','''||:new.PY||''','''||:new.PROID||''','''|| :new.JCTYPE||''','''||:new.WORKFLAG||''','''||:new.ZXFLAG||''','''||v_jwdcode||''')'; when updating then--更新数据 v_sql := 'update ITEM_REC set '|| 'PROTEAMNAME='''||replace(:new.PROTEAMNAME,'''','')||''''|| ',PY='''||:new.PY||''''|| ',PROID='''||:new.PROID||''''|| ',JCTYPE='''||:new.JCTYPE||''''|| ',WORKFLAG='''||:new.WORKFLAG||''''|| ',ZXFLAG='''||:new.ZXFLAG||''''|| ' where '|| 'ID='||:old.ID||' and JWDCODE='''||v_jwdcode||''''; when deleting then--删除数据 v_sql := 'delete from ITEM_REC t where t.ID='||:old.ID||' and t.JWDCODE='''||v_jwdcode||''''; end case; if v_sql is not null then--如果v_sql不为空,则将相应信息插入到synchro_tb_operate_log表中 insert into synchro_tb_operate_log(sd_record_id,sd_record_sql,sd_flag,create_time) values(SEQ_SYNCHRO_DATA.NEXTVAL,v_sql,0,to_char(sysdate,'YYYY-MM-DD HH24:MI:SS')); end if; exception when others then--如果执行过程中出现异常,则将异常信息插入到SYNCHRO_DATA_EXCEP_LOG表中 v_exception := substr(sqlcode||'---'||sqlerrm, 1, 500); insert into SYNCHRO_DATA_EXCEP_LOG (ID,TRIGGER_NAME,EXCEPTION_INFO,EXCEPTION_TIME) values (sys_guid(),'Trigger_DICT_PROTEAM',v_exception,to_char(sysdate,'YYYY-MM-DD HH24:MI:SS')); end TRIGGER_ITEM_REC;
什么地方不懂?
1 不懂触发器原理以及工作过程?
2 不懂那个例子?
不懂原理跟过程的话baidu一下会有很多,随便一本将数据库的书都会提到,不再赘述.这个例子可能是有点长,我给你翻译一下吧
==================================
CREATE trigger [数据库A.tr_user] on [user]
/* 建立触发器的基本语法 在数据库A的user表建立一个名字tr_user的触发器 */
for update,insert,delete
/*监视 修改 插入 删除*/
as
alter table 数据库B..[user] DISABLE TRIGGER [数据库B.tr_user]
/* 修改这个表的时候就不要做触发了,disable掉 */
-----------------------------------
if not exists (select * from deleted) --插入
/* 如果deleted表为空,那么 */
insert 数据库B..[user](username,userpass,landtime) select username,password,lastlogin from inserted
/* 将inserted表(就是对于触发器来说刚刚被插入的集合)插入到B.user */
else if not exists (select * from inserted)--删除
/* 否则 如果 inserted集合为空 */
delete 数据库B..[user] where id in (select userid from deleted)
/* 那么删除B.user下id是deleted集合中出现的id 这里用了in */
else--更新
update [user]
set
[user].username=i.username,
[user].userpass=i.password
from 数据库B..[user] as [user],
inserted as i
where [user].id=i.userid
/* update就很明显了,凡是updated的都来更新,保持一样就可以了 */
alter table 数据库B..[user] ENABLE TRIGGER [数据库B.tr_user]
这里用了一个技巧,根据inserted集合以及deleted集合来判断当前是插入或者删除,然后如果是插入的,那么另一个表删除,删除的另一个表插入.更新最简单.(可能是用来两个表互相交换数据,跟你的目的不一样)
如果你觉得难以理解,单独来创建三个触发器, insert delete update也行,这样就能减少一些判断.比如insert
你可以先删除 bbb ccc里面id in inserted的(为了防止重复),然后再全部insert进去.
不知道你为什么要这么做,感觉意义不大.明显的冗余啊.如果是想保留数据,那么定期添加一个计划任务来用数据传输服务多好... 再说备份也是很好用的.
希望我理解没有错误...余下全文>>
create trigger Mytrg
on table1
for insert
as
begin
insert into tabe2 select * from inserted
end
触发器本身的工作原理就是一条一条的处理,插入1条自动处理1次,一次批插入N条,触发器处理N次
for insert 触发器的工作原理:
DBMS在数据进行插入的时候,每插入一条记录后触发触发器,将插入的所有数据保存在inserted临时表中,
以上范例中:insert into tabe2 select * from inserted就是将inserted临时表中的数据插入到tabe2表中,
此次触发器执行完毕,系统自动删除inserted表.如果批插入多条,将再次出发此触发器
基本要求:tabe2 表结构和table1表结构一模一样