我有一个项目表&一个Items_Log表,用于记录对Item表的所有更改。
CREATE TABLE [dbo].[Items] (
[item_id] [int] IDENTITY(1,1) NOT NULL,
[item_name] [varchar](50) NOT NULL,
[item_desc] [varchar](250) NULL,
[modified_by_id] [int] NOT NULL,
[modified_date] [datetime] NOT NULL
)
CREATE TABLE [dbo].[Items_Log] (
[item_log_id] [int] IDENTITY(1,1) NOT NULL,
[item_id] [int] NOT NULL,
[item_name] [varchar](50) NOT NULL,
[item_desc] [varchar](250) NULL,
[modified_by_id] [int] NOT NULL,
[modified_date] [datetime] NOT NULL
)
Items表的更新在SPROC中执行。 ([modified_by_id]故意注释掉,如下所述)
CREATE PROCEDURE [dbo].[pUpdateItem]
@ItemID INT,
@Name VARCHAR(100),
@ByID INT
AS
UPDATE [Items] SET
item_name = @Name,
--modified_by_id = @ByID,
modified_date = GETDATE()
WHERE item_id = @ItemID;
GO
Items表上有一个Trigger,它以任何方式更新旧数据。
ALTER TRIGGER [dbo].[tItemsUpdate]
ON [dbo].[Items]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF (UPDATE(modified_by_id) AND UPDATE(modified_date))
BEGIN
INSERT INTO [Items_Log]
SELECT * FROM Deleted
END
ELSE
BEGIN
RAISERROR ('[modified_by_id] and [modified_date] must be updated.', 16, 1)
ROLLBACK TRANSACTION
END
END
为了测试触发器,[modified_by_id]被注释掉,以便调用RAISERROR。我收到了2个错误:
Msg 50000, Level 18, State 1, Procedure tItemsUpdate, Line 15
[modified_by_id] and [modified_date] must be updated.
Msg 3609, Level 16, State 1, Procedure pUpdateItem, Line 5
The transaction ended in the trigger. The batch has been aborted.
第一个错误显然是我想看到的错误,并且事务正确回滚。但我真的希望它退出而不抛出第二个错误,因为它会像这样显示给用户。
所以,根据我在其他地方看到的建议,我尝试在SPROC中进行Try ... Catch,以及在那里进行事务和回滚的正式声明(以及将Trigback从Trigger中取出)。它在SPROC中看起来像这样:
BEGIN TRY
BEGIN TRANSACTION
UPDATE [Items] SET
item_name = @Name,
--modified_by_id = @ByID,
modified_date = GETDATE()
WHERE item_id = @ItemID;
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
现在更新没有发生,但我根本没有收到任何错误消息。甚至不是来自RAISERROR的那个。
我希望我能简单地压制“Msg 3609”。这将使一切按照我想要的方式工作。但在这一点上,我几乎可以采取任何有效的解决方案。
任何人都可以帮我吗?
答案 0 :(得分:0)
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
ROLLBACK TRANSACTION;
END CATCH;
https://msdn.microsoft.com/en-us/library/ms190358.aspx
或
BEGIN CATCH
DECLARE @ErrorSeverity INT, @ErrorState INT, @ErrorMessage VARCHAR(100);
SELECT @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE(), @ErrorMessage = ERROR_MESSAGE();
ROLLBACK TRANSACTION;
RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH