2016-01-24 3 views
5

私はCRUD操作の束を取り、CUDからマージされたストアドプロシクを作成しています。私のストアドプロシージャは、このMERGE文の 'UPDATE'節にWHEN MATCHEDが複数回表示されないのはなぜですか?

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 にタイプのアクションを取得していますように見えますMERGE文の 'UPDATE'節に 'WHEN MATCHED'を複数回指定することはできません。

私はそれを解決するためにいくつかの方法を見つけましたが、私が見つけたのは、このエラーの適切な解決策ではなく、削除ではなく、レコードのIsActiveを0

また、私の検索では、なぜこのエラーがスローされているのか誰も実際に説明していません。はい、エラーはすぐそこにあるのでわかりますが、なぜこれは起こりませんか?この状況に基づいて、どのようにこれを達成するためのアイデアがありますか? @Actionが0の場合、このマージで別のstoredprocを呼び出す必要がありますか?あなたのMERGE声明の中で

+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ステートメントには、最大2つのWHEN MATCHED句を含めることができます。 * **と** * WHEN MATCHED句が2つある場合は、UPDATEアクションを指定し、DELETEアクションを指定する必要があります。* –

+0

@AaronBertrand、MERGEを使用するのは私の選択ではありませんでしたが、私はCASEまたはIF文を使用している方が良い選択だったはずです... – Chris

答えて

5

、あなたはINSERT文を使用してUPDATE声明

  • 一つで三WHEN MATCHED

    • つを持っています。

    ただし、これは許可されていません。それは明確にDocumentation on MERGEに記載されています

    MERGE文では、最大で2つのWHEN MATCHED句を持つことができます。

    そして

    2つのWHEN MATCHED句がある場合、1はUPDATEアクションを指定する必要があり、一つはDELETEアクションを指定する必要があります。また

    知ることが重要である:

    UPDATEが< >句をmerge_matched、および<merge_search_condition>に基づいてTARGET_TABLE内の行と一致する> < table_sourceの複数の行、SQLで指定されている場合サーバーがエラーを返します。 MERGEステートメントは、同じ行を複数回更新したり、同じ行を更新および削除することはできません。

  • 関連する問題