2

看下表(一个非常简化的例子):

CREATE TABLE [dbo].[tbl_Order_Lines] (
    [LineID] [int] IDENTITY(1, 1) NOT NULL ,
    [OrderID] [int] NOT NULL ,
    [StockCode] [varchar](20) NOT NULL ,
    [Quantity] [smallint] NOT NULL
)

我有一个控制插入该表的过程,但有一次你会遇到臭名昭著的“UPSERT”场景。

假设我的过程具有以下变量:

@OrderID INT ,
@StockCode VARCHAR(20) ,
@Quantity SMALLINT

我目前执行以下操作:

IF ( NOT EXISTS ( SELECT    *
                  FROM      [dbo].[tbl_Order_Lines]
                  WHERE     [OrderID] = @OrderID
                            AND [StockCode] = @StockCode )
   ) 
    INSERT  INTO [dbo].[tbl_Order_Lines]
            ( [OrderID] ,
              [StockCode] ,
              [Quantity] 
            )
    VALUES  ( @OrderID ,
              @StockCode ,
              @Quantity 
            ) 
ELSE 
    UPDATE  [dbo].[tbl_Order_Lines]
    SET     Quantity = @Quantity
    WHERE   [OrderID] = @OrderID
            AND [StockCode] = @StockCode

我的意图是废除这种旧方法并使用该MERGE声明 - 但是我正在努力理解该MERGE声明,这就是我到目前为止所拥有的:

MERGE dbo.tbl_Order_Lines
    USING ( 
    VALUES
        ( @Quantity
        ) ) AS Source ( Quantity )
    ON dbo.tbl_Order_Lines.OrderID = @OrderID AND StockCode = @StockCode
    WHEN MATCHED THEN
        UPDATE SET Quantity = source.Quantity
    WHEN NOT MATCHED THEN
        INSERT  (
                  OrderID ,
                  StockCode ,
                  Quantity 
                )        VALUES
                ( @OrderID ,
                  @StockCode ,
                  Source.Quantity 
                );

我的问题:

  1. 我在这方面的尝试MERGE似乎奏效了——但它看起来非常混乱和混乱——有没有更好的方法来写这个?
  2. 我将如何修改此MERGE语句以DELETE匹配行(基于OrderID& StockCodeif @Quantity = 0
4

2 回答 2

1

您可以使用特殊$action关键字收紧最后一部分。

Case $action 
    When 'INSERT' Then 'OK_ADDED'
    When 'UPDATE' Then 'OK_UPDATED'
    When 'DELETE' Then 'OK_REMOVED'
End

$行动

仅适用于 MERGE 语句。在 MERGE 语句的 OUTPUT 子句中指定类型为 nvarchar(10) 的列,该语句根据对该行执行的操作为每行返回三个值之一:“INSERT”、“UPDATE”或“DELETE” .

输出子句

于 2013-05-31T15:19:14.987 回答
0

好的,这就是我想出的:

MERGE dbo.tbl_Order_Lines
    USING ( VALUES ( @Quantity ) ) AS Source ( Quantity )
    ON dbo.tbl_Order_Lines.OrderID = @OrderID AND StockCode = @StockCode
    WHEN MATCHED AND @Quantity > 0 THEN
        UPDATE SET Quantity = source.Quantity
    WHEN MATCHED AND @Quantity <= 0 THEN
        DELETE
    WHEN NOT MATCHED AND @Quantity > 0 THEN
        INSERT  (
                  OrderID ,
                  StockCode ,
                  Quantity 
                )
            VALUES
                ( @OrderID ,
                  @StockCode ,
                  Source.Quantity 
                )
    OUTPUT
        COALESCE(Inserted.LineID, Deleted.LineID) AS ResultID ,
        CASE WHEN Deleted.LineID IS NULL
                  AND Inserted.LineID IS NOT NULL THEN 'OK_ADDED'
             WHEN Deleted.LineID IS NOT NULL
                  AND Inserted.LineID IS NOT NULL THEN 'OK_UPDATED'
             WHEN Deleted.LineID IS NOT NULL
                  AND Inserted.LineID IS NULL THEN 'OK_REMOVED'
        END AS ResultDesc
        INTO @tbl_LineChanges ( ResultID, ResultDesc );

仍然很想知道是否有更潮的方式来写这个!

于 2013-05-30T12:29:23.203 回答