【发布时间】:2018-04-05 01:57:58
【问题描述】:
我们在更新期间触发的表上有一个触发器。我们在前端使用实体框架。因此,我们不想在更新时看到中间结果(触发器的结果)。我的触发器中有 SET NOCOUNT ON:
ALTER TRIGGER [dbo].[trgForMedCMDWorkItemsUpdate]
ON [dbo].[MedCMDWorkItems]
AFTER UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
但是当我们执行更新时,我们首先看到中间结果,然后抛出 Entity Framework。
这里是sql命令:
Declare @UserID int
set @UserID = 26
declare @WorkItemID int
Declare @UserRoles TABLE ( roleid INT ,parentroleid INT ,rolename VARCHAR(100) )
INSERT INTO @UserRoles SELECT R.id,R.parentroleid,R.ROLE FROM userroles UR
INNER JOIN roles R ON UR.roleid = R.id WHERE UR.userid = @UserID
Update MedCMDWorkItems with (UPDLOCK) Set AssignedTo = @UserID, AssignedAt =
getdate(), LastUpdatedAt = getdate(), LastUpdatedBy = @UserID, @WorkItemID =
ID
where ID = (SELECT TOP 1 PR.ID FROM MedCMDWorkItems PR --with (UPDLOCK)
JOIN TaskTypes TT on PR.TaskTypeID = TT.ID WHERE PR.AssignedTo IS NULL AND
PR.ClosedAt IS NULL
AND Exists (SELECT 1 FROM @UserRoles WHERE roleid in (852,772)) AND
((PR.WorkItemTypeID = (select 29 FROM @UserRoles UR WHERE UR.RoleID = 852)
AND TT.Task in (SELECT Substring(UR1.rolename, Charindex('|', UR1.rolename)
+ 1, Len(UR1.rolename)) FROM @UserRoles UR1 WHERE UR1.parentroleid in (852))
) OR
(PR.WorkItemTypeID = (select 28 FROM @UserRoles UR WHERE UR.RoleID = 772)
AND TT.Task in (SELECT Substring(UR1.rolename, Charindex('|', UR1.rolename)
+ 1, Len(UR1.rolename)) FROM @UserRoles UR1 WHERE UR1.parentroleid in (772))
) )
ORDER BY (CASE WHEN PR.IsUrgent IS NULL THEN 'False' ELSE PR.IsUrgent END)
DESC, ( CASE WHEN PR.Priority IS NULL THEN 9999 ELSE PR.Priority END ),
PR.CreatedAt)
Select * From MedCMDWorkItems PRI Where ID = @WorkItemID
这里是触发器:
USE [CombinedWorkflow]
GO
/****** Object: Trigger [dbo].[trgForMedCMDWorkItemsUpdate] Script Date:
4/3/2018 5:20:22 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[trgForMedCMDWorkItemsUpdate]
ON [dbo].[MedCMDWorkItems]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
declare @NewAssignedAt DateTime;
declare @OldAssignedAt DateTime;
declare @NewPulledAt DateTime;
declare @ID int;
select @NewPulledAt = i.PulledAt from inserted i;
select @NewAssignedAt = i.AssignedAt from inserted i;
select @OldAssignedAt = d.AssignedAt from deleted d;
select @ID = i.ID from inserted i;
--If work item is being un-assigned
if(@OldAssignedAt is NOT NULL and @NewAssignedAt is NULL)
BEGIN
SET NOCOUNT ON;
Update MedCMDWorkItems
Set PulledAt = NULL
Where ID = @ID
END
--if work item is being assinged
ELSE if(@NewAssignedAt IS NOT NULL)
BEGIN
SET NOCOUNT ON;
Update MedCMDWorkItems
Set FirstAssignedAt = @NewAssignedAt
Where FirstAssignedAt is NULL and ID = @ID
END
-- if work item is being pulled
ELSE if(@NewPulledAt IS NOT NULL)
BEGIN
SET NOCOUNT ON;
Update MedCMDWorkItems
Set AssignedAt = @NewPulledAt
Where AssignedAt is NULL and ID = @ID
SET NOCOUNT ON;
Update MedCMDWorkItems
Set FirstAssignedAt = @NewPulledAt
Where FirstAssignedAt is NULL and ID = @ID
END
Select 1
END
当我在 SSMS 中执行,触发器在结果下,我得到 2 个结果,第一个表示更新了 1 行,然后第二个表示查询的结果。
如果我禁用触发器并执行命令,我不会得到第一个结果,这是启用触发器时我想要的行为。
如何设置此触发器以使其触发但不会导致其他结果?
谢谢, 萨默尔
【问题讨论】:
-
中间结果是什么意思?带有嵌入式更新的选择是什么意思?这是没有意义的。您需要在这里为我们提供更多背景信息。
-
示例数据、示例代码、预期结果?触发器有什么作用?从代码运行什么样的语句?你得到了什么样的结果?
-
您的触发器不正确,您从
insertedtable 中获取一个值到一个变量中,但是inserted表格可以有不止一行。您需要使用inserted和deleted作为表,而不是作为变量 -
也不需要一个以上的“set nocount on”,因为触发器中的第一个语句就足够了
-
删除触发器底部的
select 1。它根本没有用,甚至可能是您认为自己得到的intermediate results的原因
标签: sql sql-server entity-framework-6