SQL表同步更新问题的触发器
SQL表同步更新问题的触发器
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)
sql触发器的使用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_:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论