加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

表同步更新的问题的触发器(SQLSERVER)

发布时间:2020-12-12 16:01:21 所属栏目:MsSql教程 来源:网络整理
导读:sql server 2000 触发器,表同步更新的问题 有三个表,A ,B,C A、B表中含有: A1,B1,C1 三个字段, C 表中存放A、B表中的A1、B1、C1 的集合, 字段类型都为nvarchar(10), 当表A的数据被更新、删除、插入后要反映到C表。 当表B的数据被更新、删除、插入后要反映
sql server 2000 触发器,表同步更新的问题
  有三个表,A ,B,C
  A、B表中含有: A1,B1,C1 三个字段,
  C 表中存放A、B表中的A1、B1、C1 的集合,
  字段类型都为nvarchar(10),
  当表A的数据被更新、删除、插入后要反映到C表。
  当表B的数据被更新、删除、插入后要反映到C表。
  假定A,B表中在a1,b1,c1上有唯一索引

  这个问题如果纯属从理论来说,是很容易解决的,因为从要求可知,实质上C表存放的数据即为A、B表的并集。可以在A、B表上创建相同的trigger,一旦A、B表上有变化,比如插入、删除或更新时,即清空C表数据,然后把A、B表的数据union后插入C表中即可实现目的

呵呵呵。。。

  下面的trigger的实现原理是:

  当A表插入数据时,检查C表中是否有A表将要插入的数据,如果无,则将这行数据插入到C表中,反之,则不需要操作。

  当A表update时,检查B表中是否有更新前这行数据,如果有,则C表中应该保留这行数据且把A表中更新后的数据也插入到C表中去。如果B表中没有A表更新前的这行数据且C表中没有A表更新后的这行数据,则需要用A表更新后的数据来更新C表中与A表更新前这行数据相同的数据;如果B表中没有A表更新的的这行数据且C表中有A表更新后的这行数据,则需要从C表中删除跟A表更新前相同的那行数据(因为更新A表后,A表和B表都没有A表更新前的那行数据了,则这行数据显然在C表中不应该再存在了)。

  当A表中删除时,检查B表是否还存在A表要删除的这行数据,如果有,则不能删除C表中与A表要删除的数据相同的行。反之,则执行删除操作。

  B表中的trigger跟A表中的原理相同。

  CREATE TRIGGER SYNC_C_BY_A
  ON A
  AFTER INSERT,UPDATE,DELETE
  AS
  Declare @DmlTinyInt??--1:Insert 2:Update 3

elete
  Declare @RowsD? ? Int
  Declare @RowsI? ? Int
  Declare @A1_D? ???nvarchar(10)
  Declare @B1_D? ???Nvarchar(10)
  Declare @C1_D? ???Nvarchar(10)
  --确定是哪一种dml操作
  Select @RowsD=Count(*) From Deleted
  Select @RowsI=Count(*) From Inserted??
  If @RowsD=0 And @RowsI=0??
  ? ? Goto Exit_? ?
  If @RowsD=0 And @RowsI>0
  ? ? Set @Dml=1
  Else
  ? ?If @RowsD>0 And @RowsI>0
   Set @Dml=2
  ? ?Else
   If @RowsD>0 And @RowsI=0
  ? ???Set @Dml=3
  IF @DML=1
  ? ?BEGIN
   --检查c表中是否已经有A表中新插入的数据行,如果没有,则也插入
   IF NOT EXISTS(SELECT TOP 1 1 FROM c,inserted i where??c.a1=i.a1 and c.b1=i.b1 and c.c1=i.c1)
  ? ? insert into c select * from inserted
  ? ?END
  IF @DML=2
  ? ?BEGIN
   --检查B表中是否有A表中更新前的这行数据,如果有,则不需要更新C表中的数据,而是要把A表中更新后的这行数据插入到C表中
   IF NOT EXISTS(SELECT TOP 1 1 FROM B,DELETED d where b.a1=d.a1 and b.b1=d.b1 and b.c1=d.c1)
  ? ?BEGIN
   --如果C表中不存在A表更新后的这行数据,则更新C表中跟A表更新前那行数据相同的数据
   IF NOT EXISTS(SELECT TOP 1 1 FROM C,INSERTED I WHERE C.A1=I.A1 AND C.B1=I.B1 AND C.C1=I.C1)
  ? ???BEGIN
  ? ?UPDATE C SET A1=I.A1,B1=I.B1,C1=I.C1 FROM C,INSERTED I,DELETED D WHERE C.A1=D.A1 AND C.B1=D.B1 AND C.C1=D.C1
  ? ???END
   --如果C表中存在A表更新后的这行数据,则需要删除C表中跟A表更新前相同的那行数据
   ELSE
  ? ???BEGIN
  ? ?SELECT @A1_D=A1,@B1_D=B1,@C1_D=C1 FROM DELETED
  ? ?DELETE FROM C WHERE @A1_D=A1 AND @B1_D=B1 AND @C1_D=C1
  ? ???END
  ? ?END
   ELSE
  ? ? insert into c select * from inserted i where not exists(select 1 from c where i.a1=c.a1 and i.b1=c.b1 and i.c1=c.c1)
  ? ?END
  IF @DML=3
  ? ?BEGIN
   --如果B表中不存在A表要删除的这行数据,则需要从C表中删除这行数据
   IF not exists(select top 1 1 from b,deleted d??where b.a1=d.a1 and b.b1=d.b1 and b.c1=d.c1)
   DELETE FROM C WHERE EXISTS(SELECT 1 FROM??deleted d where??c.a1=d.a1 and c.b1=d.b1 and c.c1=d.c1)
  ? ?END
  EXIT_:??

  CREATE TRIGGER SYNC_C_BY_B
  ON B
  AFTER INSERT,DELETE
  AS
  Declare @DmlTinyInt??--1:Insert 2:Update 3

elete   Declare @RowsD? ? Int   Declare @RowsI? ? Int   Declare @A1_D? ???nvarchar(10)   Declare @B1_D? ???Nvarchar(10)   Declare @C1_D? ???Nvarchar(10)   --确定是哪一种dml操作   Select @RowsD=Count(*) From Deleted   Select @RowsI=Count(*) From Inserted??   If @RowsD=0 And @RowsI=0??   ? ? Goto Exit_? ?   If @RowsD=0 And @RowsI>0   ? ? Set @Dml=1   Else   ? ?If @RowsD>0 And @RowsI>0    Set @Dml=2   ? ?Else    If @RowsD>0 And @RowsI=0   ? ???Set @Dml=3   IF @DML=1   ? ?BEGIN    --检查c表中是否已经有B表中新插入的数据行,则也插入    IF NOT EXISTS(SELECT TOP 1 1 FROM c,inserted i where??c.a1=i.a1 and c.b1=i.b1 and c.c1=i.c1)   ? ? insert into c select * from inserted   ? ?END   IF @DML=2   ? ?BEGIN    --检查B表中是否有A表中更新前的这行数据,而是要把A表中更新后的这行数据插入到C表中    IF NOT EXISTS(SELECT TOP 1 1 FROM A,DELETED d where a.a1=d.a1 and a.b1=d.b1 and a.c1=d.c1)   ? ?BEGIN? ???    --如果C表中不存在B表更新后的这行数据,则更新C表中跟b表更新前那行数据相同的数据   IF NOT EXISTS(SELECT TOP 1 1 FROM C,INSERTED I WHERE C.A1=I.A1 AND C.B1=I.B1 AND C.C1=I.C1)   ? ? BEGIN   ??UPDATE C SET A1=I.A1,DELETED D WHERE C.A1=D.A1 AND C.B1=D.B1 AND C.C1=D.C1   ? ? END    --如果C表中存在更新B表后的这行数据,则需要删除C表中跟B表更新前相同的那行数据   ELSE   ? ? BEGIN   ??SELECT @A1_D=A1,@C1_D=C1 FROM DELETED   ??DELETE FROM C WHERE @A1_D=A1 AND @B1_D=B1 AND @C1_D=C1   ? ? End      ? ?END    ELSE   ? ? insert into c select * from inserted i where not exists(select 1 from c where i.a1=c.a1 and i.b1=c.b1 and i.c1=c.c1)   ? ?END   IF @DML=3   ? ?BEGIN    --如果A表中不存在B表要删除的这行数据,则需要从C表中删除这行数据    if not exists(select top 1 1 from a,deleted d??where a.a1=d.a1 and a.b1=d.b1 and a.c1=d.c1)    DELETE FROM C WHERE EXISTS(SELECT 1 FROM??deleted d where??c.a1=d.a1 and c.b1=d.b1 and c.c1=d.c1)   ? ?END   EXIT_: ?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读