在DbUpdateException中获取触发器的名称或错误消息
本文关键字:错误 消息 DbUpdateException 获取 触发器 | 更新日期: 2023-09-27 18:03:57
我在数据库中有几个triggers
,基于某些条件,它们可能会抛出错误和rollback transaction
。
问题是,在catch
块中,我将收到一个不包含任何有关错误原因的信息的DbUpdateException
,并且内部异常也没有任何有意义的错误消息。
我怎么能得到错误信息或触发器的名称,当我使用Entity Framework
?我需要这样做,以便能够向用户显示友好的消息。
第二个内部异常是SqlException
,但将其转换为SqlException
没有帮助,因为Procedure
是一个空字符串。
(e?.InnerException?.InnerException as System.Data.SqlClient.SqlException).Procedure
要获得触发器名称,需要将其包含在错误消息中。下面是一个样板代码示例。
CREATE TRIGGER TR_YourTable ON dbo.YourTable
FOR INSERT, UPDATE, DELETE AS
BEGIN TRY
--do something;
END TRY
BEGIN CATCH
DECLARE @ErrorMessage nvarchar(2000) =
'Error occurred in trigger ' + OBJECT_NAME(@@PROCID) + ':' + ERROR_MESSAGE();
RAISERROR(@ErrorMessage,16,1);
END CATCH;
GO
此回复假设您正在使用MSSQL Server…
在SQL代码中更改RAISERROR为:THROW 50000, <@YourErrormsg>, 16;
SQL代码注释:
-
如果你没有在你的语句后使用分号,抛出需要一个在它前面,否则它会产生错误(服务器不会让你更新触发器)。
-
如果你想在THROW之前回滚整个trans(说代码在触发器中):SET XACT_ABORT ON。与RAISERROR不同,THROWS使用XACT_ABORT来决定是否回滚(因此,如果SET XACT_ABORT OFF,也可以用于FYI消息)。
-
错误#需要=>50000. 如果您使用的数字有额外的含义,请使用特定的数字(您可以在交换机的客户端使用c# enum,我只是将触发器中的所有业务错误设置为50001,因为我只是需要消息)。
在你的c#代码中使用try catch和catch:
(Microsoft.Data.SqlClient。SqlException交货)起初,我只是(SqlException ex),但这解决了:System.Data.SqlClient。SqlException,它将不包含您的消息。使用full: Microsoft.Data.SqlClient.SqlException来捕获。
交货。消息将在sql代码中包含您的自定义集合消息。过程将具有抛出它的数据库对象的名称(在我的情况下,它也是一个触发器,所以这就是查看的地方)
我花了一段时间才弄清楚,特别是Microsoft.Data.SqlClient.SqlException vsSystem.Data.SqlClient.SqlException