2013-05-30 3 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 
       ); 

Мой вопрос (ы):

  1. Моя попытка на этом MERGE, кажется, работает - но это выглядит очень неаккуратно и сбивает с толку - есть лучший способ написания этого?
  2. Как бы я изменить это MERGE заявление в DELETE соответствующих строк (на основе OrderID & StockCode) if @Quantity = 0

ответ

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

бы еще хотелось знать если есть способ написать это!

1

Вы можете затянуть последнюю часть, используя специальное ключевое слово $action.

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

действие $

доступна только для заявления MERGE. Указывает столбец типа nvarchar (10) в предложении OUTPUT в операторе MERGE, который возвращает одно из трех значений для каждой строки: «INSERT», «UPDATE» или «DELETE», в соответствии с действием, которое было выполнено в этой строке ,

Output Clause.

Смежные вопросы