SQL Server:如果另一个表中的所有行都符合条件,则更新表

时间:2017-11-28 18:32:03

标签: sql sql-server

我有2个表,OrderOrder_ProductOrder_Product中的每个产品都有一个标记,表明产品数据是否已通过电子邮件发送(IsEmailed)。如果订单上的所有产品都已通过电子邮件发送,那么我需要将Order表更改为Order_Status_Id为2.

以下代码将更改子查询的任何行中OP.IsEmailed = 1的状态,这是不正确的。如果OP.IsEmailed = 1子查询中的所有Ordered_Product_2016,则需要更改。任何人都可以帮我一把吗?

CREATE PROCEDURE Update_Order_Status 
    @Order_Ids [dbo].Id_List READONLY
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE Order_2016
    SET Order_Status_Id = 2 -- status of 2 means emails have been sent for all products on this order
    FROM Order_2016
    WHERE Order_Id IN (SELECT Order_Id 
                       FROM Ordered_Product_2016 OP
                       WHERE OP.Order_Id IN (SELECT Id FROM @Order_Ids) 
                         AND OP.IsEmailed = 1)
END
GO

编辑 - 我可以像下面一样完成它,但想想必须有更好的方法。

CREATE PROCEDURE Update_Order_Status 
    @Order_Ids [dbo].Id_List READONLY
AS
BEGIN
    SET NOCOUNT ON;

    IF NOT EXISTS(SELECT Order_Id FROM Ordered_Product_2016 
                  WHERE Order_Id IN (SELECT Id FROM @Order_Ids) 
                    AND (IsEmailed = 0 OR IsEmailed IS NULL))
    BEGIN;
        UPDATE Order_2016
        SET Order_Status_Id = 2 -- status of 2 means emails have been sent for all products on this order
        FROM Order_2016
        WHERE Order_Id IN (SELECT Order_Id 
                           FROM Ordered_Product_2016 OP
                           WHERE OP.Order_Id IN (SELECT Id FROM @Order_Ids)  
                             AND OP.IsEmailed = 1)
    END;
END
GO

2 个答案:

答案 0 :(得分:1)

CREATE PROCEDURE Update_Order_Status 
@Order_Ids [dbo].Id_List READONLY
AS
BEGIN
SET NOCOUNT ON;

UPDATE Order_2016
SET Order_Status_Id = 2 -- status of 2 means emails have been sent for all products on this order
FROM Order_2016 o inner join Ordered_Product_2016 OP on O.Order_Id = OP.Order_Id 
WHERE not (OP.IsEmailed is null or OP.IsEmailed <> 1)

我还没有测试过。只是给你一个主意。

答案 1 :(得分:1)

以下将满足您的需求:

UPDATE O
SET Order_Status_Id = 2
FROM
    Order_2016 O
    JOIN Ordered_Product_2016 OP_Check ON O.Order_Id = OP_Check.Order_Id
    -- the above join is optional; it would prevent the updating of orders having no records in Ordered_Product_2016
    LEFT JOIN Ordered_Product_2016 OP ON
        O.Order_Id = OP.Order_Id
        AND OP.IsEmailed <> 1 OR OP.IsEmailed IS NULL
WHERE OP.Order_Id IS NULL