基于多对多关系触发插入多行

Trigger to insert multiple rows based on many-to-many relationship

我有三个表 ReservationReservation_PassengerTicket

每个预订可以有多名乘客。每次预订状态更新为 'Booked' 时,我都需要创建一个触发器来插入一张票(根据乘客数量)。我怎样才能实现它?

我尝试过的:

CREATE 
    TRIGGER Generate_Ticket 
    ON Reservation
    AFTER UPDATE
AS
    DECLARE @reservationStatus varchar(15)

    SELECT @reservationStatus =  INSERTED.Status from INSERTED

    IF @reservationStatus = 'Booked'
        BEGIN
        --stuck here

        END
GO

与将状态存储到变量中的方式相同,您也可以检索 reservationId

DECLARE @reservationStatus varchar(15)
DECLARE @reservationId int

SELECT @reservationId = INSERTED.reservationId, 
       @reservationStatus = INSERTED.Status 
FROM INSERTED

现在,在您卡住的部分,要为预订中的每位乘客创建一张票,您可以在 INSERT 中提供 SELECT 相关乘客。

INSERT INTO Ticket (passengerId, issuedDate)
       SELECT passengerId, getdate()
       FROM Reservation_Passenger
       WHERE reservationId = @reservationId

PS 您需要注意,您的代码不会在同一个 UPDATE 命令上将多个预订更改为已预订。因为在那种情况下,触发器只会触发一次,所有更新的预订都存储在 INSERTED 数据集中。您将需要使用 CURSOR 遍历所有这些预订以应用您的逻辑,或者切换到这个更简单的触发器,一步为所有预订的所有乘客创建机票:

CREATE TRIGGER Generate_Ticket ON Reservation AFTER UPDATE
AS

INSERT INTO Ticket (passengerId, issuedDate)
       SELECT P.passengerId, getdate()
       FROM INSERTED as R
            INNER JOIN Reservation_Passenger as P on P.reservationId = R.reservationID
       WHERE R.Status = 'Booked'

您还应该小心,因为在预订 table 上更新任何字段时都会触发触发器。如果您要更新另一个字段,例如对已预订的评论的评论,您的触发器将再次复制他的所有门票。

我建议您不仅要检查 INSERTED.Status = 'Booked',还要检查 DELETED.Status <> 'Booked',这样您只在状态字段时创建工单已从其他内容更改为已预订。

那就是:

CREATE TRIGGER Generate_Ticket ON Reservation AFTER UPDATE
AS

INSERT INTO Ticket (passengerId, issuedDate)
       SELECT P.passengerId, getdate()
       FROM INSERTED as I
            INNER JOIN DELETED as D on D.reservationId = I.reservationID
            INNER JOIN Reservation_Passenger as P on P.reservationId = I.reservationID
       WHERE I.Status = 'Booked' and coalesce(D.Status, '') <> 'Booked'