【问题标题】:SQL Server trigger does not update fieldsSQL Server 触发器不更新字段
【发布时间】:2020-05-22 14:03:27
【问题描述】:

我是 SQL Server 触发器的新手,我尝试编写一个不符合我要求的触发器。我确信有一个明显的原因,但我看不出问题所在?你们中是否有更熟练的人看到我在触发脚本中所做的任何明显错误? 插入或更新表预订时会发生什么实际上并没有什么,但我曾希望当列 FareTypeID = 'FAKT' 时 FareToCollect 列已更改为 0。

ALTER TRIGGER [dbo].[Fare] 
   ON  [dbo].[Booking] 
   AFTER INSERT,UPDATE
   AS 
BEGIN
SET NOCOUNT ON;

Declare @bo_id int
Declare @leg_id int
Declare @fare_sum real
Declare @Payment_Type_Id varchar

Select @bo_id = inserted.bookingid from inserted
Select @fare_sum = inserted.fareamount from inserted
Select @leg_id = ba.LegId from BookingActivity ba inner join BookingLegs bl on bl.LegId=ba.LegId where bl.BookingId=@bo_id and bl.LegNum=0
Select @Payment_Type_Id = inserted.PaymentTypeId from inserted

IF  @Payment_Type_Id = 'FAKT'
    BEGIN
        UPDATE Booking
        SET FareToCollect = 0
        FROM inserted ins
        INNER JOIN booking bo on ins.BookingId=bo.BookingId 

        UPDATE BookingActivity
        SET FareAmount = 0
        FROM BookingActivity 
        WHERE BookingActivity.LegId=@leg_id
    END;
ELSE
    BEGIN
        UPDATE Booking
        SET FareToCollect = @fare_sum
        FROM inserted ins
        INNER JOIN booking bo on ins.BookingId=bo.BookingId

        UPDATE BookingActivity
        SET FareAmount = @fare_sum
        FROM BookingActivity
        WHERE BookingActivity.LegId=@leg_id 
    END

END

【问题讨论】:

  • 用您正在使用的数据库标记您的问题,大概是 SQL Server。
  • 触发器是基于 SET 的。不是基于 RBAR(逐行列)。您需要根据设置进行重构。

标签: sql sql-server triggers database-trigger sql-server-2017


【解决方案1】:

评论太长了。

你的触发器刚刚坏了。破绽从第一行代码开始:

select @bo_id = inserted.bookingid from inserted;

这假设inserted 只有一行。但这不是一个有效的假设。在 SQL Server(与大多数其他数据库不同)中,触发器是基于 set 的。 inserted(和deleted)“表”引用可以有多行。

考虑到这一点,您需要重写整个触发器。对于大多数操作,inserteddeleted 可用于基于集合的逻辑。在某些情况下,您可能需要使用游标或其他机制遍历每个值。

【讨论】:

    猜你喜欢
    • 2012-08-01
    • 2011-06-03
    • 1970-01-01
    • 2010-11-18
    • 2014-03-26
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    • 1970-01-01
    相关资源
    最近更新 更多