Tôi đang tham gia một loạt các ý kiến của CRUD và tạo các bản lưu trữ hợp nhất khỏi CUD. proc lưu trữ của tôi trông như thế nàyTại sao WHEN MATCHED 'không thể xuất hiện nhiều hơn một lần trong mệnh đề' CẬP NHẬT 'của tuyên bố MERGE?
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;
Khi tôi đi đến thực hiện điều này tôi nhận được lỗi đầy đủ này
Msg 10.714, Level 15, State 1, Thủ tục usp_AdministrationHistoryMerge, Line 36 Một hành động của loại 'WHEN MATCHED' không thể xuất hiện nhiều hơn một lần trong mệnh đề 'CẬP NHẬT' của câu lệnh MERGE.
Tôi đã xem xét trên SO và tìm thấy một số cách để giải quyết vấn đề này, nhưng những gì tôi đã tìm thấy không phải là giải pháp phù hợp cho lỗi này, thay vì xóa và tôi cần cập nhật IsActive của bản ghi thành 0.
Ngoài ra, trong tìm kiếm của tôi, không ai thực sự giải thích tại sao lỗi này được ném ra, vâng tôi biết rõ ràng vì lỗi ở ngay đó, nhưng tại sao điều này không được phép xảy ra? và dựa trên hoàn cảnh này có ý tưởng nào về cách thực hiện điều này không? hoặc tôi có nên hợp nhất này gọi một storedproc khác khi @Action là 0?
Bạn có chắc chắn muốn sử dụng 'MERGE' không? https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/ –
Nó được ghi rõ trong [tài liệu về MERGE] (https://msdn.microsoft.com /en-us/library/bb510625.aspx): * Câu lệnh MERGE có thể có tối đa hai mệnh đề WHCH MATCHED. * ** và ** * Nếu có hai mệnh đề WHEN MATCHED, thì người ta phải chỉ định một hành động UPDATE và người ta phải chỉ định một hành động DELETE.* –
@AaronBertrand, Nó không phải là lựa chọn của tôi để sử dụng MERGE, tôi hình bằng cách sử dụng một câu lệnh CASE hoặc IF sẽ là lựa chọn tốt hơn ... Bài viết hay nhất theo cách – Chris