`
seawavenews
  • 浏览: 230334 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

表同步更新的问题的触发器(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 @DmlTinyInt  --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 @DmlTinyInt  --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_: 

 

-------------------------------------------

EXEC sp_renamedb 'accounting', 'financial'   --sql2000修改表名

--------------------------------------------------

如何使触发器失效,但是不删除触发器,然后又如何使无效的触发器激活  
---------------------------------------------------------------  
 
禁用并重新启用触发器  
下例使用  ALTER  TABLE  的  DISABLE  TRIGGER  选项来禁用触发器,以使正常情况下会违反触发器条件的插入操作得以执行。然后下例使用  ENABLE  TRIGGER  重新启用触发器。  
CREATE  TABLE  trig_example    
(id  INT,    
name  VARCHAR(20),  
salary  MONEY)  
go  
--  Create  the  trigger.  
CREATE  TRIGGER  trig1  ON  trig_example  FOR  INSERT  
as    
IF  (SELECT  COUNT(*)  FROM  INSERTED  
WHERE  salary  >  100000)  >  0  
BEGIN  
print  'TRIG1  Error:  you  attempted  to  insert  a  salary  >  $100,000'  
ROLLBACK  TRANSACTION  
END  
GO  
--  Attempt  an  insert  that  violates  the  trigger.  
INSERT  INTO  trig_example  VALUES  (1,'Pat  Smith',100001)  
GO  
--  Disable  the  trigger.  
ALTER  TABLE  trig_example  DISABLE  TRIGGER  trig1  
GO  
--  Attempt  an  insert  that  would  normally  violate  the  trigger  
INSERT  INTO  trig_example  VALUES  (2,'Chuck  Jones',100001)  
GO  
--  Re-enable  the  trigger.  
ALTER  TABLE  trig_example  ENABLE  TRIGGER  trig1  
GO  
--  Attempt  an  insert  that  violates  the  trigger.  
INSERT  INTO  trig_example  VALUES  (3,'Mary  Booth',100001)  
GO  

分享到:
评论

相关推荐

    SQLServer触发器实现不同服务器数据同步.pdf

    SQL Server 触发器实现不同服务器数据同步 在本文中,我们将探讨如何使用 SQL Server 触发器来实现不同服务器之间的数据同步。该方法可以实现在两个或多个服务器之间实时同步数据,提高数据的一致性和可靠性。 ...

    sqlserver 创建触发器 远程服务器相应执行SQL语句

    本文将详细介绍如何在SQL Server中创建触发器来实现当本地数据库发生数据插入时,在远程服务器上相应地执行SQL语句,实现数据同步。这通常用于需要跨数据库同步数据的应用场景。 #### 准备工作 在开始之前,确保...

    SqlServer触发器调用WebService

    ### SqlServer触发器调用WebService知识点详解 #### 一、SqlServer触发器简介 在了解如何通过Sql Server触发器调用WebService之前,我们首先需要对触发器有一个基本的认识。触发器是一种特殊的存储过程,它被定义...

    sqlserver触发器例子

    触发器是SQL Server中一种特殊的存储过程,其特点在于不能被显式地调用,而是当对特定表进行数据操作(如插入、更新或删除)时自动激活。通过这种方式,触发器能够帮助实现复杂的业务逻辑和数据完整性约束。 #### ...

    SQL SERVER 触发器视频讲解

    在SQL Server中,触发器是一种特殊的存储过程,它在数据库中的特定事件发生时自动执行,如数据插入、更新或删除操作。本视频讲解将深入探讨触发器的创建、编辑、修改及其功能,帮助用户更好地理解和应用这些技术。 ...

    SQL server存储过程习题,SQL触发器习题.rar

    在SQL Server数据库管理系统中,存储过程和触发器是两种非常重要的数据库编程元素,它们对于数据库设计和数据管理具有深远的影响。下面将详细讲解这两个概念及其相关的知识点。 **SQL存储过程**: 1. **定义**:SQL...

    第05节:SQLServer触发器Demo源代码.rar

    这个资源“第05节:SQLServer触发器Demo源代码.rar”很可能是包含了一个C#项目,该项目演示了如何在应用程序中创建、使用和管理SQL Server触发器。通过学习和理解这些示例代码,开发者可以更好地掌握在C#环境中操作...

    SQL Server 触发器 表的特定字段更新时,触发Update触发器

    在SQL Server中,触发器是一种特殊的存储过程,它在数据更改操作(如INSERT,UPDATE或DELETE)发生时自动执行。触发器可以用于实现复杂的业务规则和数据验证,以确保数据库中的数据完整性。在这个例子中,我们关注的...

    sqlA库某表到B库某表同步

    "sqlA库某表到B库某表同步"这个标题涉及到的就是如何将一个SQL Server数据库(sqlA)中的某个表的数据实时或定时地更新到另一个SQL Server数据库(sqlB)的相应表中。下面我们将深入探讨这个过程,以及相关的SQL ...

    SQL Server触发器

    当用户试图更新视图时,触发器会执行实际的更新操作,不仅更新视图本身,还会同步更新产品、客户和销售这三张底层表。这样,通过视图的更新操作,可以方便地维护多表之间的数据一致性。 总的来说,SQL Server触发器...

    两台SQL-Server数据同步解决方案

    ### 两台SQL Server数据同步解决方案详解 #### 一、概述 在当今信息化时代,数据同步成为企业级应用中不可或缺的一部分。特别是在分布式环境中,确保不同地理位置的数据库保持一致性和实时性变得尤为重要。本文将...

    SQL server 触发器,在触发Merge过程中,逐行触发的解决办法 用group by 避免是一次触发中的多行更新或删除。

    在SQL Server中,触发器是一种数据库对象,它可以在数据更改(INSERT、UPDATE或DELETE)时自动执行。在处理大量数据的Merge操作时,触发器可能会一次性处理多行,这可能导致性能问题或者不符合预期的行为。标题和...

    SQLServer恢复表级数据详解

    本文将详细介绍SQLServer中用于快速恢复表级数据的方法,并对各方案的利弊进行对比说明。 首先,需要明确的是,防范措施永远比事后补救要有效得多。但在实际工作中,仍然可能出现因操作不当导致数据损坏的情况。...

    sqlserver与mysql数据库同步

    本主题将深入探讨如何实现SQL Server与MySQL数据库之间的数据同步,这对于确保数据一致性、实时性以及跨平台的数据交换具有重大意义。 首先,我们需要了解SQL Server和MySQL是两种不同类型的数据库管理系统。SQL ...

    SqlServer连接工具

    它包含了对SQL Server实例的各种管理工具,例如对象资源管理器,用于浏览和操作数据库、表、存储过程、触发器等数据库对象;查询编辑器,支持Transact-SQL语句的编写和执行;以及脚本生成器,帮助用户创建和维护...

    在VS2008下,利用c#在SQLSERVER2005实现两个数据库同步

    在开发过程中,有时我们需要在不同的SQL Server 2005数据库之间进行数据同步,例如在测试环境和生产环境之间同步数据,或者在多个分部的数据库间共享信息。本教程将详细讲解如何在Visual Studio 2008(VS2008)环境...

    SQL Server数据库中使用触发器经验谈

    总的来说,SQL Server中的触发器是强大的工具,可以增强数据库的逻辑功能,但需谨慎使用,以免引入不必要的性能问题和复杂性。在设计数据库时,应充分考虑触发器的影响,并确保其逻辑清晰,便于维护。

Global site tag (gtag.js) - Google Analytics