2016-01-24 87 views
5

我正在做一堆CRUD操作並創建CUD合併storedprocs。我的存儲過程是這樣的爲什麼WHEN MATCHED'不能在MERGE語句的'UPDATE'子句中出現多次?

CREATE PROCEDURE usp_AdministrationHistoryMerge 
    @AdministrationHistoryID int out, 
    @AdministratorID int, 
    @DateCreated datetime, 
    @CreatedBy nvarchar(50), 
    @ModifiedBy nvarchar(50), 
    @Action int 
AS 

SET NOCOUNT OFF 
SET TRANSACTION ISOLATION LEVEL READ COMMITTED 

DECLARE @ERROR_SEVERITY int, 
     @MESSAGE varchar(1000), 
     @ERROR_NUMBER int, 
     @ERROR_PROCEDURE nvarchar(200), 
     @ERROR_LINE int, 
     @ERROR_MESSAGE nvarchar(4000), 
     @IsActive bit, 
     @DateModified datetime; 
begin try 
    if @Action = 1 
     begin 
      set @IsActive = 1 
      set @AdministrationHistoryID = SCOPE_IDENTITY() 
     end 
    merge [AdministrationHistory] as target 
    using (select @AdministratorID, @DateCreated, @CreatedBy, @DateModified, @ModifiedBy, @IsActive) 
    as source (AdministratorID, DateCreated, CreatedBy, DateModified, ModifiedBy, IsActive) 
    on (target.AdministrationHistoryID = source.AdministrationHistoryID) 
    when matched and @Action = -1 then 
     update 
      set IsActive = 0 
    when matched and @Action = 0 then 
     update 
     set ModifiedBy = @ModifiedBy, 
     DateModified = GETDATE() 
    when matched and @Action = 1 then 
    insert 
    (AdministratorID, DateCreated, CreatedBy, IsActive) 
    values 
    (@AdministratorID, @DateCreated, @CreatedBy, @IsActive); 
end try 

BEGIN CATCH 
    SET @ERROR_SEVERITY = ISNULL(ERROR_SEVERITY(),''); 
    SET @ERROR_NUMBER = ISNULL(ERROR_NUMBER(),''); 
    SET @ERROR_PROCEDURE = ISNULL(ERROR_PROCEDURE(),''); 
    SET @ERROR_LINE = ISNULL(ERROR_LINE(),''); 
    SET @ERROR_MESSAGE = ISNULL(ERROR_MESSAGE(),''); 

    -- Test if the transaction is uncommittable. 
    IF (XACT_STATE()) = -1 
     BEGIN 
      --PRINT N'The transaction is in an uncommittable state. Rolling back transaction.' 
      ROLLBACK TRANSACTION; 
     END; 

    -- Test if the transaction is active and valid. 
    IF (XACT_STATE()) = 1 
     BEGIN 
      --PRINT N'The transaction is committable. Committing transaction.' 
      COMMIT TRANSACTION; 
     END; 

    SET @MESSAGE = 'Error Occured in Stored Procedure ' + cast(@ERROR_PROCEDURE as varchar(200)) + 
        '; Line Number ' + cast(@ERROR_LINE as varchar) + 
        '; Message: [' + cast(@ERROR_NUMBER as varchar) + '] - ' 
        + cast(@ERROR_MESSAGE as varchar(255)) 

    RAISERROR(@MESSAGE, @ERROR_SEVERITY, 1); 
END CATCH; 

當我去執行這個我得到這個完整的錯誤

消息10714,級別15,狀態1,過程usp_AdministrationHistoryMerge,36號線 類型的動作'WHEN MATCHED'不能在MERGE語句的'UPDATE'子句中出現多次。

我環顧四周,發現了一些方法來解決這個問題,但是我發現這個錯誤並不適合解決這個問題,而不是刪除,我需要將記錄的IsActive更新爲0.

此外,在我的搜索沒有人真正解釋爲什麼這個錯誤被拋出,是的,我知道它很明顯,因爲錯誤是在那裏,但爲什麼這是不允許發生?基於這種情況,有沒有關於如何做到這一點的想法?或者當@Action爲0時,我應該有這個合併調用另一個storedproc?

+0

您是否確信要使用MERGE? https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/ –

+3

它在[MERGE文檔](https://msdn.microsoft.com /en-us/library/bb510625.aspx):* MERGE語句最多可以有兩個WHEN MATCHED子句。 * **和** *如果有兩個WHEN MATCHED子句,則必須指定一個UPDATE動作,並且必須指定一個DELETE動作。* –

+0

@AaronBertrand,使用MERGE不是我的選擇,我使用CASE或IF語句的數字會是更好的選擇......好的文章的方式 – Chris

回答

5

在你MERGE聲明中,你有三個WHEN MATCHED條款

  • 兩個與UPDATE聲明
  • 一個與INSERT聲明。

但是,這是不允許的。它在Documentation on MERGE明確提出:

MERGE語句可以有最多兩個WHEN MATCHED條款。

而且

如果有兩個WHEN MATCHED條款,則必須指定一個UPDATE動作和一個必須指定DELETE行動。

而且重要的是要知道的是:

如果UPDATE在<指定merge_matched >條款,以及超過<table_source>的一排target_table基於<merge_search_condition>,SQL相匹配的行服務器返回一個錯誤。 MERGE語句不能多次更新同一行,或者更新和刪除同一行。

相關問題