插入后使用触发器更新多行(sql server)

Posted

技术标签:

【中文标题】插入后使用触发器更新多行(sql server)【英文标题】:update multiple rows with trigger after insert (sql server) 【发布时间】:2011-12-10 15:50:32 【问题描述】:

我有一个包含订单产品的表 orderDetails

产品标识 颜色 尺寸 数量

还有一张桌子

产品标识 尺寸 颜色 库存

订单完成后,我使用此查询将项目插入表 orderDetails

INSERT INTO orderDetail(orderId, productId, productColor, productSize, productQuantity , cost productName)
    SELECT     
       @orderId, products_translations.id, cart.productColor, cart.productSize, 
       cart.productQuantity, cart.cost, products_translations.name
    FROM cart 
    INNER JOIN products_translations ON cart.productID = products_translations.id
    WHERE     
        (cart.cartId = @cartId) AND 
        (products_translations.language = 1)

然后我在表orderDetails上有一个触发器:

ALTER TRIGGER [dbo].[scalaProdotti]
   ON [dbo].[orderDetail]
   FOR INSERT
AS

DECLARE @size int
DECLARE @color char(6)
DECLARE @quantity int
DECLARE @product int

BEGIN
    SELECT @size = productSize FROM inserted
    SELECT @color = productColor FROM inserted
    SELECT @quantity = productQuantity FROM inserted
    SELECT @product = productId FROM inserted
    UPDATE stock SET quantity =  quantity - @quantity WHERE size=@size AND color=@color AND product=@product
END

有了这个触发器,我想减少库存,但只有第一个产品受到影响,其他数量保持不变。

我错过了什么?

谢谢。

【问题讨论】:

【参考方案1】:

要点是:您假设将针对插入的每一行调用触发器 - 不是这种情况

您的触发器将每个语句调用一次 - 但该语句可以一次插入多行。

在这种情况下,触发器内的Inserted 表将包含多行,并且您的语句:

SELECT @size = productSize FROM inserted
SELECT @color = productColor FROM inserted
SELECT @quantity = productQuantity FROM inserted
SELECT @product = productId FROM inserted

将失败或碰巧只选择插入的第一行而忽略其余的插入。

您需要重写触发器以应对Inserted 可以同时包含多个插入的行这一事实

触发器中的代码应如下所示:

UPDATE stock 
FROM Inserted i
SET 
     stock.quantity = quantity - i.quantity 
WHERE 
     stock.size = i.size 
     AND stock.color = i.color 
     AND stock.product = i.product

【讨论】:

以上是关于插入后使用触发器更新多行(sql server)的主要内容,如果未能解决你的问题,请参考以下文章

插入和更新后未触发 SQL Server 触发器

在 Microsoft SQL Server 上插入触发器后 -- 更新新创建记录中的列

在 Sql Server 中插入或更新多行

在 SQL Server 触发器中处理多行

Sql Server 2005 - 插入更新触发器 - 获取更新,插入行

SQL Server 2017 触发器将旧值作为更新后的新值