中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 数据库开发 > 数据库综合
表同步更新的问题的触发器(SQLSERVER)
作者:未知 时间:2005-09-13 23:43 出处:Blog.ChinaUnix.net 责编:chinaitpower
              摘要:表同步更新的问题的触发器(SQLSERVER)

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 @Dml            TinyInt  --1:Insert 2:Update 3:Delete           
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,UPDATE,DELETE
AS
Declare @Dml            TinyInt  --1:Insert 2:Update 3:Delete           
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表中更新前的这行数据,如果有,则不需要更新C表中的数据,而是要把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,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表中存在更新B表后的这行数据,则需要删除C表中跟B表更新前相同的那行数据
            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
       --如果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_:    

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有