2013-05-30 33 views
2

採取如下表(一個非常簡單的例子):使用SQL MERGE與瓦爾而不是表

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 
       ); 

我的問題(S):

  1. 我在這個MERGE嘗試似乎工作 - 但它看起來非常凌亂和混亂 - 有沒有寫這更好的辦法?
  2. 我將如何修改這個MERGE聲明DELETE匹配的行(基於OrderID & StockCodeif @Quantity = 0

回答

0

OK,這就是我想出了:

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); 

還是很想知道如果有這種寫作方式!

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' 。

Output Clause