【发布时间】:2013-01-27 18:16:40
【问题描述】:
我在SQL Server 2008 R2中已经用这种方式实现了一个触发器-
ALTER TRIGGER [dbo].[trgtblOrgStaffAssocLastUpdate] ON [dbo].[tblOrgStaffAssoc]
AFTER UPDATE
AS
IF EXISTS (SELECT i.* FROM INSERTED i inner join deleted d on i.ORG_ID = d.ORG_ID and isnull(i.StaffType, -1111) = isnull(d.StaffType, -1111)
where i.Deleted = 0
and (isnull(i.PER_ID, cast(cast(0 as binary) as uniqueidentifier)) <> isnull(d.PER_ID, cast(cast(0 as binary) as uniqueidentifier))
))
BEGIN
IF EXISTS (SELECT * FROM DELETED)
BEGIN
--UPDATE PER_ID
update l
set PER_ID = 1, UpdatedOn = GETDATE()
from dbo.tblOrgStaffAssocLastUpadate l inner join [dbo].[inserted] i on l.ORG_ID = i.ORG_ID and l.StaffType = i.StaffType
inner join [dbo].[deleted] d on i.ORG_ID = d.ORG_ID and i.StaffType = d.StaffType
where isnull(i.PER_ID, cast(cast(0 as binary) as uniqueidentifier)) <> isnull(d.PER_ID, cast(cast(0 as binary) as uniqueidentifier))
END
END
我的目的是在更新 tblOrgStaffAssoc 时更新 tblOrgStaffAssocLastUpadate。只有一排,它工作正常。但是对于一批发送的多行,它仅在 tblOrgStaffAssocLastUpadate 更新一行,而 tblOrgStaffAssoc 更新了多行。
当我使用中间表 _Inserted 和 _deleted 来缓冲 INSERTED 和 DELETED 数据并使用永久表像这样更新时 -
ALTER TRIGGER [dbo].[trgtblOrgStaffAssocLastUpdate] ON [dbo].[tblOrgStaffAssoc]
AFTER UPDATE
AS
IF EXISTS (SELECT i.* FROM INSERTED i inner join deleted d on i.ORG_ID = d.ORG_ID and isnull(i.StaffType, -1111) = isnull(d.StaffType, -1111)
where i.Deleted = 0
and (isnull(i.PER_ID, cast(cast(0 as binary) as uniqueidentifier)) <> isnull(d.PER_ID, cast(cast(0 as binary) as uniqueidentifier))
))
BEGIN
IF EXISTS (SELECT * FROM DELETED)
BEGIN
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[_inserted]') AND type in (N'U'))
insert into [dbo].[_inserted]
select * from inserted
else
select * into [dbo].[_inserted]
from inserted
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[_deleted]') AND type in (N'U'))
insert into [dbo].[_deleted]
select * from deleted
else
select * into [dbo].[_deleted]
from deleted
--UPDATE PER_ID
update l
set PER_ID = 1, UpdatedOn = GETDATE()
from dbo.tblOrgStaffAssocLastUpadate l inner join [dbo].[_inserted] i on l.ORG_ID = i.ORG_ID and l.StaffType = i.StaffType
inner join [dbo].[_deleted] d on i.ORG_ID = d.ORG_ID and i.StaffType = d.StaffType
where isnull(i.PER_ID, cast(cast(0 as binary) as uniqueidentifier)) <> isnull(d.PER_ID, cast(cast(0 as binary) as uniqueidentifier))
END
END
它工作正常。将永久表 _Inserted 更改为使用 #inserted 或表变量 @inserted 也不起作用。
显然使用永久表不是一个好主意。我不知道触发器是如何以这种方式工作的。有人可以帮忙吗?
谢谢
编辑以回答@usr 的评论 -
如果我使用它就不能正常工作-
update l set PER_ID = 1, UpdatedOn = GETDATE() from dbo.tblOrgStaffAssocLastUpadate l inner join [dbo].[inserted] i on l.ORG_ID = i.ORG_ID and l.StaffType = i.StaffType inner join [dbo].[deleted] d on i.ORG_ID = d.ORG_ID and i.StaffType = d.StaffType where isnull(i.PER_ID, cast(cast(0 as binary) as uniqueidentifier)) <> isnull(d.PER_ID, cast(cast(0 as binary) as uniqueidentifier))
只有一行被更新。其余行根本不更新。即使我可以看到返回多行,如果我使用
select l.* from dbo.tblOrgStaffAssocLastUpadate l inner join [dbo].[inserted] i on l.ORG_ID = i.ORG_ID and l.StaffType = i.StaffType inner join [dbo].[deleted] d on i.ORG_ID = d.ORG_ID and i.StaffType = d.StaffType where isnull(i.PER_ID, cast(cast(0 as binary) as uniqueidentifier)) <> isnull(d.PER_ID, cast(cast(0 as binary) as uniqueidentifier))
就在更新语句之前。这就是我完全困惑的地方,为什么下一个更新语句只更新一行,为什么只有永久表可以持久更新所有行而不是临时表和表变量。
更新问题 -
由于多个更新行在单个批次中发送到表。似乎触发器的 INSERT 和 DELETE 表只有一个,最后一个仅在我到达“update l”语句时才更新行。在此之前,它包含多个更新行。当我使用永久表时,我可以看到这一点。我只是不明白 SQL Server 的行为方式。有人看到同样的东西吗?
【问题讨论】:
-
为什么还需要所有这些表?
--UPDATE PER_ID下的查询看起来不错。为什么你不能单独使用它? -
@usr 感谢您的快速回复。如果我在 l.ORG_ID = i.ORG_ID 和 l.StaffType = i 上使用 " update l set PER_ID = 1, UpdatedOn = GETDATE() from dbo.tblOrgStaffAssocLastUpadate l inner join [dbo].[inserted] i,它将无法正常工作.StaffType 内部连接 [dbo].[deleted] d on i.ORG_ID = d.ORG_ID 和 i.StaffType = d.StaffType 其中 isnull(i.PER_ID, cast(cast(0 as binary) as uniqueidentifier)) isnull (d.PER_ID, cast(cast(0 as binary) as uniqueidentifier))"。仅更新一行。其余行根本不更新
-
@usr 如果我插入 " select l.* from dbo.tblOrgStaffAssocLastUpadate l inner join [dbo].[inserted] i on l.ORG_ID = i.ORG_ID and l,我什至可以看到返回的多行.StaffType = i.StaffType 内部连接 [dbo].[deleted] d on i.ORG_ID = d.ORG_ID 和 i.StaffType = d.StaffType 其中 isnull(i.PER_ID, cast(cast(0 as binary) as uniqueidentifier) ) isnull(d.PER_ID, cast(cast(0 as binary) as uniqueidentifier)) " 在更新语句之前。我很困惑为什么下一个更新语句只更新一行。
-
请不要将代码示例或示例数据放入 cmets - 因为您无法对其进行格式化,所以阅读它非常困难....而是:更新您的问题,编辑它以提供附加信息!谢谢。
标签: sql sql-server sql-server-2008 triggers sql-update