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

bttbmeg0  于 2022-10-31  发布在  其他
关注(0)|答案(2)|浏览(172)

我在数据库中有几个triggers,根据某些条件,它们可能会抛出一个错误和rollback transaction
问题是,在catch块中,我将收到一个DbUpdateException,它不包含任何有关错误原因的信息,内部异常也没有任何有意义的错误信息。
当我使用Entity Framework时,如何获得错误消息或触发器的名称?我需要这样做,以便能够向用户显示友好的消息。
第二个内部异常是SqlException,但将其转换为SqlException并没有帮助,因为Procedure是空字符串。

(e?.InnerException?.InnerException as System.Data.SqlClient.SqlException).Procedure
piok6c0g

piok6c0g1#

要获取触发器名称,您需要在错误消息中包含该名称。

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
busg9geu

busg9geu2#

此回复假定您使用的是MSSQL Server...如果不忽略...
在您的SQL代码中,将RAISERROR更改为:扔50000,〈@你的错误消息〉,16 ;
有关SQL代码的说明:
1.如果语句后没有使用分号,THROWS需要在前面使用分号,否则会产生错误(服务器不会让您更新触发器)。
1.如果要在THROW之前回滚整个事务(假设代码在触发器中),请执行以下操作:SET XACT_ABORT ON。与RAISERROR不同,THROWS使用XACT_ABORT来确定是否回滚(因此,如果SET XACT_ABORT OFF,则也可用于FYI消息)。
1.错误号需要=〉50000。如果您使用的数字有其他含义,请使用特定的数字(您可以在开关中的客户端使用C#枚举,我只是将触发器中的所有业务错误设置为50001,因为我只需要消息)。
在C#程式码中,使用try catch搭配catch:
在一开始的时候,我只是有(SqlException ex),但是它解析为:系统.数据.SqlClient.SqlException,它将不会包含您的消息。请使用完整的:异常错误。
例如,Messsage将在SQL代码中包含自定义设置消息。例如,Prodecure将包含抛出该消息的数据库对象的名称(在我的情况下,它也是一个触发器,因此这就是要查找的位置)
这花了我一段时间才弄明白,尤其是微软的。数据。SqlClient.SqlException系统。数据。SqlClient.SqlException

相关问题