【问题标题】:sql server 2008 multiple inserts over 2 tablessql server 2008 多次插入超过 2 个表
【发布时间】:2010-04-27 18:40:52
【问题描述】:

我在我的 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
)

【问题讨论】:

  • 请问表架构是什么?
  • 对不起荷兰语和英语的混合。但我在荷兰工作,在这里翻译只是为了更好地理解;-)

标签: sql sql-server-2008 triggers insert


【解决方案1】:

这个子查询有几个问题:

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 的一部分。

第三,此触发器在插入行之后运行,因此它会始终匹配,因此您的触发器将始终引发错误并回滚。

您可以修复触发器,但更好的方法是根本不使用触发器。如果我理解您正在尝试正确执行的操作,您所需要的只是对 flight, seatUNIQUE 约束:

ALTER TABLE passgier
ADD CONSTRAINT IX_passagier_flightseat
UNIQUE (flight, seat)

【讨论】:

  • 我要做的是用一个插入语句插入两个(或更多)乘客。示例中的乘客乘坐不同的航班。我会用索引尝试你的建议。好一个,没想到!
  • @Aaronaught 感谢您的快速和良好的响应!好像用索引解决了!感谢您的精彩提示。
【解决方案2】:

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

【讨论】:

  • 一个触发器似乎不起作用。我刚刚尝试过,管理工作室说“2 行受到影响”,但没有任何反应
  • 您是否在触发器中再次插入?使用 INSTEAD OF 触发器,您必须在触发器中进行实际插入(如果数据通过您的测试)。无论如何,我看到 Aaronaught 的好主意对你有用,所以这是个好消息。
【解决方案3】:

它可能会通过在表中找到自身来引发错误(循环引用回到自身)。您可能希望在 where 子句中添加一个额外的过滤器,例如“AND Passenger.ID inserted.ID”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多