sql server 2008多个插入2个表

时间:2010-04-27 18:40:53

标签: sql sql-server-2008 triggers insert

我的sql server 2008数据库上有以下触发器

CREATE TRIGGER tr_check_stoelen
ON Passenger
AFTER INSERT, UPDATE
AS
BEGIN
        IF EXISTS(
                SELECT 1
                FROM Passenger p 
                INNER JOIN Inserted i on i.flight= p.flight
                WHERE p.flight= i.flightAND p.seat= i.seat
             )
        BEGIN
            RAISERROR('Seat taken!',16,1)
            ROLLBACK TRAN   
        END
END

当我尝试运行下面的查询时,触发器会抛出错误。这个查询我应该在两个不同的航班上的数据库中插入两个不同的乘客。我确定两个座位都没有被占用,但我无法弄清楚为什么触发器会给我错误。是否必须对相关做些什么?

INSERT INTO passagier VALUES 
(13392,5315,3,'Janssen Z','2A','October 30, 2006 10:43','M'),
(13333,5316,2,'Janssen Q','2A','October 30, 2006 11:51','V')

更新: 该表如下所示

CREATE TABLE Passagier
(
    passengernumber int NOT NULL CONSTRAINT PK_passagier PRIMARY KEY(passagiernummer),
    flight int NOT NULL CONSTRAINT FK_passagier_vlucht REFERENCES vlucht(vluchtnummer) 
        ON UPDATE NO ACTION ON DELETE NO ACTION,
    desk int NULL CONSTRAINT FK_passagier_balie REFERENCES balie(balienummer) 
        ON UPDATE NO ACTION ON DELETE NO ACTION,
    name varchar(255) NOT NULL,
    seat char(3) NULL,
    checkInTime datetime NULL,
    gender char(1) NULL
)

3 个答案:

答案 0 :(得分:6)

此子查询存在一些问题:

SELECT 1
FROM Passenger p 
INNER JOIN Inserted i on i.flight= p.flight
WHERE p.flight= i.flight AND p.seat= i.seat

首先,WHERE p.flight = i.flight是非常不必要的,因为它已经是您加入的一部分。

其次,p.seat = i.seat也应该是JOIN的一部分。

第三,此触发器在插入行之后运行,因此总是匹配,因此您的触发器总是引发错误并回滚。

您可以修复触发器,但更好的方法是根本不使用触发器。如果我了解您要正确执行的操作,则只需UNIQUEflight, seat ALTER TABLE passgier ADD CONSTRAINT IX_passagier_flightseat UNIQUE (flight, seat) 约束:

{{1}}

答案 1 :(得分:2)

如果在插入记录后运行触发器,然后查找包含刚刚插入的值的记录,则始终可以找到它。您可以尝试使用INSTEAD OF触发器,以便在实际插入之前检查现有记录。

答案 2 :(得分:0)

它可能通过在表中找到自己来抛出错误(循环引用回到自身)。您可能希望在where子句中添加其他过滤器,例如“AND Passenger.ID<> inserted.ID”