将SQL Server异常传递给.net

时间:2013-01-28 17:05:43

标签: c# sql sql-server exception-handling

存储过程:

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

。调用存储过程的网络代码:

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试试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时,我得到:

  

Msg 50000,Level 16,State 1,Procedure GetLocalConfig,Line 70
  8134遇到零除错误。

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

2 个答案:

答案 0 :(得分:1)

我假设您从GetLocalConfig SP返回的错误行未使用LocalConfigDtoMapper进行映射,它期望采用不同的架构。

因此,您禁止实际的exeption,并返回错误架构的行。这会导致将零长度序列或空可枚举返回给调用者。当Single()检查断言你只有一行时,它会抛出相应的异常,因为你没有。


如果要在出错时回滚,请查看这些重复项

How to rollback a transaction in TSQL when string data is truncated?

SQL Server 2008 Transaction, rollback required?

SQL Server - transactions roll back on error?

Essentialy

您可以在CATCH块中使用RAISERROR重新引发错误。您可以使用ERROR_ ...函数

获取原始“例外”详细信息

SET XACT_ABORT ON

答案 1 :(得分:0)

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