我有一个更新触发器,当在另一个表中更新记录时更新空记录。我的问题是数据是在gridview中,当你更新它时,它会对网格中的所有记录运行更新查询,而不仅仅是更新的记录。因此,当触发器触发时,它会更新目标表中匹配的每一行,但我只想更新数据已更改的那一行。这是我的触发器。
ALTER TRIGGER [dbo].[Trigger_update_DeSchedule] ON [dbo].[tBatchDetails]
After UPDATE ,INSERT
AS
BEGIN
SET NOCOUNT ON
DECLARE @BatchId int
, @Ethanol varchar(10)
, @Glucose varchar(10)
, @SampleAge varchar(10);
SELECT @BatchId = B.[BatchID]
,@Ethanol = [Ethanol]
,@Glucose= [Glucose]
,@SampleAge = SA.SampleAge
from INSERTED bd
INNER JOIN [dbo].[tSampleAge] sa ON SA.SampleAgeID = BD.SampleAge
INNER JOIN [dbo].[tBatch] b ON B.ID =BD.ID
UPDATE [dbo].[DeSchedule]
SET [Ethanol] = @Ethanol
, [Glucose] = @Glucose
, [SampleCompleted] = 1
WHERE [BatchID] = @BatchId
AND [SampleAge] = @SampleAge
AND SiteID = 6
AND SampleCompleted IS NULL
END
如何在此触发器中仅更新数据已更改的记录?
答案 0 :(得分:0)
评论太长了。
您应该做的第一件事是分离您的插入和更新触发器。在单个触发器中执行它们几乎总是会导致问题。这肯定会给你带来麻烦。您发布的代码应该在插入时执行您要查找的内容。
但是,更新时需要添加要删除的联接。然后,您需要为基表中的每个列添加谓词。知道实际值是否已更改的唯一方法是比较插入和删除的值。
这样的事情:
i.ColA <> d.ColA
OR i.ColB <> d.ColB
etc...
有人可能会说使用UPDATE功能,但这不适合你。如果列位于要更新的值列表中,则返回true。它不关心值是否与以前相同。
您当前的触发器正在使用标量值。这不是一个好方法,因为触发器每次操作触发一次。您的代码需要基于。
答案 1 :(得分:0)
对于每个Update语句触发的触发器不是针对update语句中的每一行,当更新更新多行时,在Trigger中使用Variables会导致数据失败/损坏。
ALTER TRIGGER [dbo].[Trigger_update_DeSchedule] ON [dbo].[tBatchDetails]
After UPDATE ,INSERT
AS
BEGIN
SET NOCOUNT ON
-- Correct the Alias in the set clause I am not sure what is coming from where
UPDATE S
SET S.[Ethanol] = [Ethanol]
, S.[Glucose] = [Glucose]
, S.[SampleCompleted] = 1
from INSERTED bd
INNER JOIN [dbo].[tSampleAge] sa ON SA.SampleAgeID = BD.SampleAge
INNER JOIN [dbo].[tBatch] b ON B.ID =BD.ID
INNER JOIN [dbo].[DeSchedule] s ON s.[BatchID] = B.[BatchID]
AND s.[SampleAge] = BD.SampleAge
WHERE SiteID = 6
AND SampleCompleted IS NULL
END