首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用多个插入时,SQL server 2008触发器无法正常工作。

使用多个插入时,SQL server 2008触发器无法正常工作。
EN

Stack Overflow用户
提问于 2010-05-04 01:40:05
回答 4查看 3.2K关注 0票数 0

我有下面的触发器;

代码语言:javascript
运行
复制
CREATE TRIGGER trFLightAndDestination
ON checkin_flight
AFTER INSERT,UPDATE
AS
BEGIN
    IF NOT EXISTS
    (
                    SELECT 1 
            FROM Flight v
            INNER JOIN Inserted AS i ON i.flightnumber = v.flightnumber
            INNER JOIN checkin_destination AS ib ON ib.airport = v.airport
            INNER JOIN checkin_company AS im ON im.company = v.company
            WHERE i.desk = ib.desk AND i.desk = im.desk
    )
    BEGIN
        RAISERROR('This combination of of flight and check-in desk is not possible',16,1)
        ROLLBACK TRAN       
    END
END

我希望触发器所做的是在添加checkin_flight的新记录时检查表Flight、checkin_destination和checkin_company。checkin_flight的每一条记录都包含一个航班号和服务台号码,乘客需要在这些地方办理登机手续。表checkin_destination和checkin_company包含有关公司和目的地的信息,这些公司和目的地仅限于某些登机柜台。在向checkin_flight添加记录时,我需要来自flight表的信息,以便通过插入的航班号获得目的地和航班公司。此信息需要与航班、目的地和公司的可用登机组合进行核对。

我使用如上所述的触发器,但是当我尝试插入错误的组合时,触发器允许这样做。这里我漏掉了什么?

编辑1:我使用了以下多个insert语句

代码语言:javascript
运行
复制
INSERT INTO checkin_flight VALUES (5315,3),(5316,3),(5316,2)
//5315 is the flightnumber, 3 is the desknumber to checkin for that flight

编辑2:测试了单行插入,这是不可能的,然后错误被抛出正确。所以看起来是多重插入导致了这个问题。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-05-04 01:55:05

问题是您的逻辑允许任何至少包含一组有效值的插入通过。它只会在所有插入的记录都无效的情况下失败,而不是在任何插入的记录无效的情况下失败。

更改您的“如果不存在(...)”添加到语句"IF EXISTS(...)“并更改SELECT语句以返回无效的航班。

例如:

代码语言:javascript
运行
复制
IF EXISTS
(
                SELECT 1 
        FROM Flight v
        INNER JOIN Inserted AS i ON i.flightnumber = v.flightnumber
        LEFT JOIN checkin_destination AS ib ON ib.airport = v.airport
             AND i.desk = ib.desk
        LEFT JOIN checkin_company AS im ON im.company = v.company
             AND i.desk = im.desk
        WHERE (im.desk IS NULL OR ib.desk IS NULL)
)
BEGIN
    RAISERROR('This combination of of flight and check-in desk is not possible',16,1)
    ROLLBACK TRAN       
END
票数 1
EN

Stack Overflow用户

发布于 2010-05-04 01:51:18

我不确定您的业务逻辑,但您需要检查查询是否做了正确的事情。

您的问题是IF NOT EXISTS,如果插入的3行中有1行的条件为真,则它不存在。您需要将其转换为找到问题行,并使用IF EXISTS,然后使用error out。

但是,在触发器中出错的最好方法是:

代码语言:javascript
运行
复制
RAISERROR()
ROLLBACK TRANSACTION
RETURN

我有点怀疑缺少RETURN是不是你的问题,但在触发器中出错时,最好包括三个R

票数 1
EN

Stack Overflow用户

发布于 2010-05-04 01:57:01

插入的表可以包含多行,因此触发器中的所有逻辑必须能够应用于所有行。触发器必须每行触发一次的想法效果是对WRT触发器的一个常见误解。SQL Server将倾向于合并对触发器的调用,以提高在同一事务中发生的调用的性能。

要解决这个问题,您可以从inserted的COUNT()开始,并将其与匹配条件的COUNT()进行比较,如果存在不匹配,则引发错误。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2759982

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档