sql server触发器的问题

sufsoft 2013-08-15 11:58:53
有一个业务需要用到触发器:当users表中的某个user的信息被更新或者有新的user被insert进来的话,就把更新了的user信息或者新insert的user信息插入到另一个表backUpUsers.
我这边用到的是after update,insert的写法,然后从inserted内存表中拿user的数据。但是执行后发现,更新了的user信息可以插入到backUpUsers表中,但是更新前的那个user信息也会插入到backUpUsers表中。
不知道说清楚没有,举个例子吧:

users表
user_id user_name user_age user_tel user_address
1 s1234567A tester1 20 13787346725 beijing
2 s1234567B tester2 20 15876239087 sichuan

backUpUsers表
user_id user_name user_age user_tel user_address backUp_dte
1 s1234567A tester1 20 13787346725 beijing 2013-08-12
2 s1234567B tester2 20 15876239087 sichuan 2013-08-13

此时,users表中的user s1234567A的电话和住址被更新了,那么此时就要通过触发器把更新后的user s234567A重新insert到backUpUsers表中去,正确的情况下,backUpUsers表中的数据应该是这样:
backUpUsers表
user_id user_name user_age user_tel user_address backUp_dte
1 s1234567A tester1 20 13787346725 beijing 2013-08-12
2 s1234567B tester2 20 15876239087 sichuan 2013-08-13
3 s1234567A tester1 20 13087652378 shanghai 2013-08-14

但是现在却成了这样:
backUpUsers表
user_id user_name user_age user_tel user_address backUp_dte
1 s1234567A tester1 20 13787346725 beijing 2013-08-12
2 s1234567B tester2 20 15876239087 sichuan 2013-08-13
3 s1234567A tester1 20 13787346725 beijing 2013-08-12
4 s1234567A tester1 20 13087652378 shanghai 2013-08-14

也就是说,在insert更新的信息同时也把原来的user s1234567A又重新insert到backUpUsers表中,这个是不对的,那为什么会出现这种情况呢,希望大家可以帮着分析一下!!!


...全文
155 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
sufsoft 2013-08-23
  • 打赏
  • 举报
回复
一直忙着忘了结贴了,谢谢shawn
Shawn 2013-08-18
  • 打赏
  • 举报
回复
引用 5 楼 sufsoft 的回复:
谢谢,算是给了我一个思路。但是有个小问题,我update时可以触发触发器,并且把更新的user信息插到bakckup表去了,但是insert的时候不知道是没触发触发器,还是我的写法有问题,新的user并没有被插到backup表里边。我这边针对insert操作是这么写的: IF EXISTS(SELECT 1 FROM inserted) AND NOT EXISTS(SELECT 1 FROM deleted)
这样没有问题。楼主再看一下自己的逻辑吧。
CREATE TRIGGER tr_aaaa ON dbo.a
AFTER UPDATE, INSERT
as
begin
	IF EXISTS(SELECT 1 FROM inserted) AND NOT EXISTS(SELECT 1 FROM deleted) 
	BEGIN
		SELECT inscnt=COUNT(*) FROM inserted
	end  
	ELSE
	BEGIN
		SELECT inscnt=COUNT(*) FROM INSERTED
		SELECT delcnt=COUNT(*) FROM deleted      
	end  
END
sufsoft 2013-08-18
  • 打赏
  • 举报
回复
引用 4 楼 wwwwgou 的回复:
--sorry,不小心给提交了,参考如下
create trigger tr_test on users
after insert,update
as
BEGIN
	IF EXISTS
	(
		SELECT 1 FROM DELETED
	)  
	BEGIN
		insert into usersBackup(user_id,user_name,user_age,user_tel,user_address,backupdate)
		select user_id,user_name,user_age,user_tel,user_address,getdate() 
		from INSERTED A
			INNER JOIN DELETED D
				ON A.USER_ID = B.USER_ID
		WHERE  a.user_tel <> b.user_tel OR a.user_address <> b.user_address
	END  
	ELSE
	BEGIN
		insert into usersBackup(user_id,user_name,user_age,user_tel,user_address,backupdate)
		select user_id,user_name,user_age,user_tel,user_address,getdate() 
	END  
end
谢谢,算是给了我一个思路。但是有个小问题,我update时可以触发触发器,并且把更新的user信息插到bakckup表去了,但是insert的时候不知道是没触发触发器,还是我的写法有问题,新的user并没有被插到backup表里边。我这边针对insert操作是这么写的: IF EXISTS(SELECT 1 FROM inserted) AND NOT EXISTS(SELECT 1 FROM deleted)
sufsoft 2013-08-16
  • 打赏
  • 举报
回复
引用 1 楼 wwwwgou 的回复:
#1.从你描述的逻辑看,没有问题。要看看你的触发器是怎么写的,才能知道原因。代码参考如下: create trigger tr_test on users after insert,update as begin insert into usersBackup(user_id,user_name,user_age,user_tel,user_address,backupdate) select user_id,user_name,user_age,user_tel,user_address,getdate() from inserted end #2.如果不是上面的原因,那么有可能你其它的地方又触发了此触发器,或同时INSERTED表中同时有多条记录。
关于你的第一点,我这边和你差不多, 都是从inserted拿到数据然后做相关逻辑操作再插入到backup表中去的。 至于你说的第二点,我目前无法确定是不是其他地方触发了他,可能存在一种情况:当update的时候,即使user的信息没有实质性的更新,但数据库的确是执行力update操作,这个也会导致插入相同的user去backup表的吧。有没有一种方式来确定只有user的信息真正被更新时才插入到backup表里面去呢?
Shawn 2013-08-16
  • 打赏
  • 举报
回复
#1.从你描述的逻辑看,没有问题。要看看你的触发器是怎么写的,才能知道原因。代码参考如下: create trigger tr_test on users after insert,update as begin insert into usersBackup(user_id,user_name,user_age,user_tel,user_address,backupdate) select user_id,user_name,user_age,user_tel,user_address,getdate() from inserted end #2.如果不是上面的原因,那么有可能你其它的地方又触发了此触发器,或同时INSERTED表中同时有多条记录。
Shawn 2013-08-16
  • 打赏
  • 举报
回复
--sorry,不小心给提交了,参考如下
create trigger tr_test on users
after insert,update
as
BEGIN
	IF EXISTS
	(
		SELECT 1 FROM DELETED
	)  
	BEGIN
		insert into usersBackup(user_id,user_name,user_age,user_tel,user_address,backupdate)
		select user_id,user_name,user_age,user_tel,user_address,getdate() 
		from INSERTED A
			INNER JOIN DELETED D
				ON A.USER_ID = B.USER_ID
		WHERE  a.user_tel <> b.user_tel OR a.user_address <> b.user_address
	END  
	ELSE
	BEGIN
		insert into usersBackup(user_id,user_name,user_age,user_tel,user_address,backupdate)
		select user_id,user_name,user_age,user_tel,user_address,getdate() 
	END  
end
Shawn 2013-08-16
  • 打赏
  • 举报
回复
引用 2 楼 sufsoft 的回复:
关于你的第一点,我这边和你差不多, 都是从inserted拿到数据然后做相关逻辑操作再插入到backup表中去的。 至于你说的第二点,我目前无法确定是不是其他地方触发了他,可能存在一种情况:当update的时候,即使user的信息没有实质性的更新,但数据库的确是执行力update操作,这个也会导致插入相同的user去backup表的吧。有没有一种方式来确定只有user的信息真正被更新时才插入到backup表里面去呢?
虽然,物理上,update fieldvalue = fieldvalue,记录不用做任何改变,但仍然会触发触发器,会插入到backup表中。如果想不插入,触发器中再加逻辑即可:

27,582

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧