包含两个 WHEN MATCHED 的 MERGE 语句

MERGE statement with two WHEN MATCHED

我的 MERGE 语句运行良好:

MERGE INTO product_replenishment PR
USING ( SELECT * FROM traxs_temp..__MinMaxImport WHERE session_id = @session_id ) T
    ON T._product = PR.product AND T._branch_no = PR.branch_no
WHEN MATCHED AND T._stock_warehouse IS NOT NULL THEN
    UPDATE SET
        date_time_updated = GETDATE(),
        user_no_updated = @user_no,
        stock_warehouse = T._stock_warehouse
WHEN NOT MATCHED BY TARGET AND T._stock_warehouse IS NOT NULL THEN
    INSERT 
        (date_time_created,
        date_time_updated,
        user_no_created,
        user_no_updated,
        branch_no,
        product,
        stock_warehouse,
        archive) 
    VALUES 
        (GETDATE(),
        GETDATE(),
        @user_no,
        @user_no,
        T._branch_no,
        T._product,
        T._stock_warehouse,
        0);

我想添加另一个 WHEN MATCHED 语句,如下所示:

WHEN MATCHED AND T._stock_warehouse IS NOT NULL THEN
    UPDATE SET
        date_time_updated = GETDATE(),
        user_no_updated = @user_no,
        stock_warehouse = T._stock_warehouse
WHEN MATCHED AND T._stock_warehouse IS NULL THEN
    UPDATE SET
        date_time_updated = GETDATE(),
        user_no_updated = @user_no,
        archive = 1

但是我得到一个错误:An action of type 'WHEN MATCHED' cannot appear more than once in a 'UPDATE' clause of a MERGE statement.

难道我想做的事情不可能实现吗?

可以使用 CASE 表达式模拟一般情况,如我在 , or in this blog post here 中所示。但是你的情况更具体,因为这两个条款之间的区别比一般情况更简单。您可以将它们组合成一个子句:

WHEN MATCHED THEN UPDATE SET
  -- These are always updated the same way, regardless of the WHEN MATCHED AND predicate
  date_time_updated = GETDATE(),
  user_no_updated = @user_no,

  -- These depend on the relevant WHEN MATCHED AND predicate, so use CASE
  stock_warehouse = CASE 
    WHEN T._stock_warehouse IS NOT NULL THEN T._stock_warehouse 
    ELSE stock_warehouse
  END,
  archive = CASE WHEN T._stock_warehouse IS NULL THEN 1 ELSE archive END