我想弄清楚一下触发器!请各位能否解答我心中的疑问呢?谢谢!

时间:2021-07-11 05:04:11
1:触发器是单条记录的触发,执行对象是一个确定的记录.(这个没错吧?)
2:在修改更新触发器中,我想在触发器中执行:更新其它字段的数据,那么这个执行过程是否会再次触发一次触发器呢?如果是的话,那么它不会死循环触发吗?
3;在问题2中,我想更新本记录的其它字段,我怎么更新比较快?我使用 update XX set A=***,B=***.....这样好像是更新所有记录的啊!如果在最后加一个 where ID=(select ID from Inserted)这样不是很麻烦了?

暂时想到这么几个问题!等有疑问再来问!
谢谢大家的支持!

8 个解决方案

#1


1:我曾经测试过,从delphi中批处理执行时,触发器可能是一条一条触发的因为我使用了select @count=count(*) from inserted 来跟踪发现每次都是执行的if @count=1的子句。而用insert into一次插入时插入的是@count>1的子句,这肯定是多条记录触发。
2:那是触发器递归,数据库有属性 nested triggers 用来设置是否递归。嵌套数据库只允许有32曾,如果把递归看成一种嵌套那也只能是32层,所以不会死循环。
3:应该只能加where。

#2


第二个问题能不能在触发器里面禁用了触发器自己,然后更新某个记录,更新完以后再启用该触发器.这样不就不会导致触发器的多次触发了?

第三个问题能否在update inserted set ................这个来更新该记录?

第一个问题:如果插入的是批的话,我好像曾经出现过错误,说更新涉及过多的行!

#3


1. 可以多条语句同时触发
2. 触发器最多可以潜逃32层触发
3.那个条件应该必须加上吧, 如不加岂不是会更新好多无辜的资料行嘛?

#4


第三个问题能否在update inserted set ................这个来更新该记录? 不可以!!

#5


你的第二个问题可能是你的设计有问题,一般自己触发自己同一个字段很少见的,你最好把你的情况说清楚。
另外成批加入的时候你用游标吧,这个应该可以解决问题。

#6


//更新其它字段的数据,那么这个执行过程是否会再次触发一次触发器呢?如果是的话,那么它不会死循环触发吗?

不會的。
你可以定義當更新哪個字段時,才執行這段代碼;如果不更新這個字段,就不執行這段代碼。

CREATE TRIGGER dbo.trU_timecard
ON dbo.timecard
AFTER UPDATE
AS
IF UPDATE(first_start_sign) OR UPDATE(first_end_sign) 
BEGIN
............
....
END

GO

#7


1   执行的对象可以是整个数据库
2   触发器一般是针对经常处理的对象而处理的(如果不是则手动好一点)

#8


谢谢大家的指点!谢谢!(国际惯例):)
引用:ck4587() ( ) :
你的第二个问题可能是你的设计有问题,一般自己触发自己同一个字段很少见的,你最好把你的情况说清楚。
我来说一下!
因为我的某个表有2个字段是连接另外一个表的主键(唯一标识),这里有人会问,怎么不使用视图(因为如果使用了视图的话,旧的数据会因为某些表的记录改变的时候改变,而收费这些事情已经成为了历史,不能修改当时的状况,例如当年的附加费,当年的用水单价等等,因此使用触发器更新某个表中的某些字段),触发是在这个表的2个记录另外一个表的主键的字段改变的时候,使用触发器更新相关的信息.

hdhai9451(※★山,快馬加鞭未下鞍...☆※) 
这位兄弟说到的有道理,不过你在提醒我之前我不知道有这个东西!在这再次谢谢你的指点,
IF UPDATE(first_start_sign) OR UPDATE(first_end_sign) 
你这个是判断first_start_sign 和first_en_sign字段是否改变的语句吗?如果是的话那实在太好了,我以前一直使用的是: if (select first_star_sign from inserted)<>(select first_star_sign from deleted)来判断(大概是这个意思吧,不过我使用变量判断前一个和后一个的.)






#1


1:我曾经测试过,从delphi中批处理执行时,触发器可能是一条一条触发的因为我使用了select @count=count(*) from inserted 来跟踪发现每次都是执行的if @count=1的子句。而用insert into一次插入时插入的是@count>1的子句,这肯定是多条记录触发。
2:那是触发器递归,数据库有属性 nested triggers 用来设置是否递归。嵌套数据库只允许有32曾,如果把递归看成一种嵌套那也只能是32层,所以不会死循环。
3:应该只能加where。

#2


第二个问题能不能在触发器里面禁用了触发器自己,然后更新某个记录,更新完以后再启用该触发器.这样不就不会导致触发器的多次触发了?

第三个问题能否在update inserted set ................这个来更新该记录?

第一个问题:如果插入的是批的话,我好像曾经出现过错误,说更新涉及过多的行!

#3


1. 可以多条语句同时触发
2. 触发器最多可以潜逃32层触发
3.那个条件应该必须加上吧, 如不加岂不是会更新好多无辜的资料行嘛?

#4


第三个问题能否在update inserted set ................这个来更新该记录? 不可以!!

#5


你的第二个问题可能是你的设计有问题,一般自己触发自己同一个字段很少见的,你最好把你的情况说清楚。
另外成批加入的时候你用游标吧,这个应该可以解决问题。

#6


//更新其它字段的数据,那么这个执行过程是否会再次触发一次触发器呢?如果是的话,那么它不会死循环触发吗?

不會的。
你可以定義當更新哪個字段時,才執行這段代碼;如果不更新這個字段,就不執行這段代碼。

CREATE TRIGGER dbo.trU_timecard
ON dbo.timecard
AFTER UPDATE
AS
IF UPDATE(first_start_sign) OR UPDATE(first_end_sign) 
BEGIN
............
....
END

GO

#7


1   执行的对象可以是整个数据库
2   触发器一般是针对经常处理的对象而处理的(如果不是则手动好一点)

#8


谢谢大家的指点!谢谢!(国际惯例):)
引用:ck4587() ( ) :
你的第二个问题可能是你的设计有问题,一般自己触发自己同一个字段很少见的,你最好把你的情况说清楚。
我来说一下!
因为我的某个表有2个字段是连接另外一个表的主键(唯一标识),这里有人会问,怎么不使用视图(因为如果使用了视图的话,旧的数据会因为某些表的记录改变的时候改变,而收费这些事情已经成为了历史,不能修改当时的状况,例如当年的附加费,当年的用水单价等等,因此使用触发器更新某个表中的某些字段),触发是在这个表的2个记录另外一个表的主键的字段改变的时候,使用触发器更新相关的信息.

hdhai9451(※★山,快馬加鞭未下鞍...☆※) 
这位兄弟说到的有道理,不过你在提醒我之前我不知道有这个东西!在这再次谢谢你的指点,
IF UPDATE(first_start_sign) OR UPDATE(first_end_sign) 
你这个是判断first_start_sign 和first_en_sign字段是否改变的语句吗?如果是的话那实在太好了,我以前一直使用的是: if (select first_star_sign from inserted)<>(select first_star_sign from deleted)来判断(大概是这个意思吧,不过我使用变量判断前一个和后一个的.)