2

存储过程:

Procedure GetLocalConfig
(
    @ConfigId int
)
AS
SET NOCOUNT ON; 
BEGIN TRY
BEGIN TRANSACTION
SELECT 1/0
COMMIT TRANSACTION;
END TRY
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;  


     IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
        RETURN 
END CATCH

.Net 代码调用存储过程:

try
{
return DatabaseFactory.CreateDatabase(ConnectionStringConfigName)
       .ExecuteSprocAccessor(DbCommands.GetLocalConfig, new LocalConfigDtoMapper(), configId)
       .Single();

}
catch (Exception ex)
{
   // Exception : Sequence contains no elements???
}

如果我从 SSMS 执行这个 SP,我会得到实际的异常:

ErrorNumber ErrorSeverity ErrorState  ErrorProcedure ErrorLine   ErrorMessage
8134        16            1           GetLocalConfig 54           Divide by zero error encountered.

我想在.Net 的 try catch 块中看到这个异常,但是我不断得到 Sequence 不包含任何元素。

经过一些研究,我发现我可以在我的存储过程中出现 RAISEERROR Try catch 块:

DECLARE @errnum nchar(5), @errmsg nvarchar(2048);
SELECT
   @errnum = RIGHT('00000' + ERROR_NUMBER(), 5),
   @errmsg = @errnum + ' ' + ERROR_MESSAGE();
RAISERROR (@errmsg, 16, 1);

现在,当我使用 SSMS 运行 SP 时,我得到:

消息 50000,级别 16,状态 1,过程 GetLocalConfig,第 70 行
8134 除以零错误。

但是 .Net 仍然给了我同样的异常,在这种情况下如何让异常传递给 .Net?

4

2 回答 2

1

我假设您从GetLocalConfigSP 返回的错误行没有使用 映射LocalConfigDtoMapper,它需要不同的架构。

因此,您抑制了实际的异常,并返回了带有错误模式的行。这导致将零长度序列或空可枚举返回给调用者。当Single()检查断言您只有一行时,它会引发适当的异常,因为您没有。


如果您想回滚错误,请查看这些重复项

截断字符串数据时如何回滚TSQL中的事务?

SQL Server 2008 事务,需要回滚吗?

SQL Server - 事务回滚错误?

本质

RAISERROR您可以在您的CATCH块中重新提出错误。ERROR_您可以使用... 函数获取原始“异常”详细信息

或者

SET XACT_ABORT ON

于 2013-01-28T17:19:11.440 回答
0

SP 中的 TRY CATCH 块抑制了实际的错误消息,删除了我在应用程序中得到实际异常的消息。

于 2013-01-28T17:21:47.460 回答