在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

在DbUpdateException中获取触发器的名称或错误消息

要获得触发器名称,需要将其包含在错误消息中。下面是一个样板代码示例。

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代码注释:

  1. 如果你没有在你的语句后使用分号,抛出需要一个在它前面,否则它会产生错误(服务器不会让你更新触发器)。

  2. 如果你想在THROW之前回滚整个trans(说代码在触发器中):SET XACT_ABORT ON。与RAISERROR不同,THROWS使用XACT_ABORT来决定是否回滚(因此,如果SET XACT_ABORT OFF,也可以用于FYI消息)。

  3. 错误#需要=>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