VB.Net 没有捕获存储过程 raiserror

Posted

技术标签:

【中文标题】VB.Net 没有捕获存储过程 raiserror【英文标题】:VB.Net is not catching stored procedure raiserror 【发布时间】:2013-10-22 00:24:49 【问题描述】:

是否有人已经遇到过这种错误,例如存储过程引发错误但客户端(vb.net)没有捕捉到错误?

下面是我从 vb.net 调用存储过程的代码

Try

       Dim exec_refreshdependentviews As String = String.Format("EXEC REFRESHDEPENDENTVIEWS '0', '1', 2 ", tableName, usercode, isCreateNew)

       Using refreshCommand As New SqlClient.SqlCommand(exec_refreshdependentviews, DirectCast(sqlTransaction.Connection, SqlClient.SqlConnection), DirectCast(sqlTransaction, SqlClient.SqlTransaction))                  
               refreshCommand.ExecuteNonQuery()
       End Using
Catch exc As SqlClient.SqlException
        Throw New Exception("REFRESHDEPENDENTVIEWS", exc)
Catch ex As Exception
        Throw New Exception("REFRESHDEPENDENTVIEWS", ex)
End Try

在存储过程中我引发了一个错误,其消息来自 SP 内部遇到的累积错误。

RAISERROR  (@Errors, 16, 1)

请注意@Errors 有一个值。

当我尝试通过后端运行脚本时,我可以在消息选项卡中看到错误消息。

EXEC RefreshDependentViews 'CustomerSalesOrder', 'admin', 1 

以下是累积的错误信息。

消息 50000,级别 16,状态 6,过程 RefreshDependentViews,行 216 无效的对象名称“dbo._Merged_SalesOrder_with_Details”。消息 50000,级别 16,状态 1,过程 RefreshDependentViews,第 216 行 无效的对象名称“Hips54.dbo.SupplierPurchaseReceiptDetailView”。 消息 50000,级别 16,状态 1,过程 RefreshDependentViews,行 299 运行 RefreshDependentViews CustomerSalesOrder 时出错:未能 SP_REFRESHVIEW _Merged_SalesOrder_。消息:无效的对象名称 'dbo._Merged_SalesOrder_with_Details'。错误运行 RefreshDependentViews CustomerSalesOrder:SP_REFRESHVIEW 失败 _SOG_新。消息:无效的对象名称“Hips54.dbo.SupplierPurchaseReceiptDetailView”。

上述错误没有被 vb.net 中的 try-catch 捕获。这就像我的 SP 中没有引发错误

【问题讨论】:

RAISERROR 在 SP 中的哪个位置? 显示您的 SP 代码。如果 SP 抛出一个错误,VB.NET 将捕获该错误。 【参考方案1】:

我已将您的代码简化为仅查询异常

Try
  Using refreshCommand As New SqlClient.SqlCommand("RAISERROR  ('test', 16, 1)", cn)
      refreshCommand.ExecuteNonQuery()
  End Using
Catch exc As SqlClient.SqlException
  Throw New Exception("REFRESHDEPENDENTVIEWS", exc)
Catch ex As Exception
  Throw New Exception("REFRESHDEPENDENTVIEWS", ex)
End Try

它会按预期抛出由第一个捕获捕获的异常。所以看来问题出在存储过程上。我会尝试更改严重性(16 -> 20)以抑制服务器代码中可能的捕获。

【讨论】:

【参考方案2】:

感谢您的回复。我现在找到了罪魁祸首。

在我的代码中,我在 SqlClient.SqlCommand 中使用 sqlTransaction,这就是 try-catch 块没有捕获 raiserror 的问题的原因。

以下是导致问题的代码:

sqlTransaction = sqlConnection.BeginTransaction(IsolationLevel.ReadCommitted)
Me.RefreshDependentViews(connectionString, objectsToRefresh(i), m_UserCode)
sqlTransaction.Commit()

我在存储过程中的代码

DECLARE @Errors NVARCHAR(MAX), @Error NVARCHAR(100)
BEGIN TRY              
    BEGIN TRANSACTION
    EXEC RefreshTableColletionOnView @TableName, @UserCode
    COMMIT TRANSACTION          
END TRY              
BEGIN CATCH
    ROLLBACK TRANSACTION;

    SET @Error = 'Warning: Failed to RefreshDataDictionaryColumn ' + @tablename
    IF @Errors IS NULL
        SET @Errors = @Error + '.' + CHAR(13) + 'Message: ' + ERROR_MESSAGE() 
    ELSE
        SET @Errors = @Errors + @Error + '.' + CHAR(13) + 'Message: ' + ERROR_MESSAGE()

END CATCH

IF @Errors IS NOT NULL
BEGIN
    RAISERROR (@Errors, 16, 1)              
END

我不知道为什么在通过 VB.Net 调用 SP 时 @Errors 为空的原因,但如果我通过 MSSQL 运行它,@Errors 有错误值。

【讨论】:

以上是关于VB.Net 没有捕获存储过程 raiserror的主要内容,如果未能解决你的问题,请参考以下文章

从 .NET 中的 SQL Server 捕获 RAISERROR

RAISERROR

使用 VB.NET 程序运行存储过程 [重复]

在存储过程中设置 RAISERROR 的编号和消息

SQL存储过程内部RaisError客户端抓不住弹不出错误的解决

如何将 vb.net 中日期的空值传递给 sql 存储过程?