无法捕获绕过try..catch的SQL Server SP错误

问题描述 投票:0回答:1

我有一个SQL Server存储过程。如果我在代码周围放置try块,它只会捕获某些错误,而只是将一些错误推送到SSMS消息窗口。我认为文档(TryCatch)表示try..catch块未捕获某些错误(例如,从不存在的表中进行选择)

在我的例子中,示例是通过同义词选择不存在的列,该列将其发送到“消息”输出窗格:

Msg 207,第16级,状态1,程序dbo.TestSP,第185行[Batch Start Line 2]无效的列名称'InvalidColumn'。

但是,我从代码而不是SSMS运行SP,并且没有返回任何错误或异常。

具体地说,我的Command Execute方法只是返回而不会引发异常,返回值是一个空值,因此我完全不知道记录或报告给用户的错误是什么。我也尝试过完全删除try块,结果相同。

我在VBA中使用了老式的ADODB,但是同样的原理也适用于.Net,我查看了Command对象的属性,那里似乎没有太多,返回的状态为0。

有什么方法可以在我的Command或Connection对象中的任何地方捕获或发现这些错误,以便我可以记录它们,而不仅仅是简单地说“未知错误”?

作为示例,我的存储过程如下,并且具有无效列的select语句会引发如上所示的错误,而不会引发错误。

ALTER PROCEDURE [dbo].[TestSP]
AS
BEGIN
 SET NOCOUNT ON;
 BEGIN TRY
    declare @returnCode int;
    If object_id('syn_xxx','SN') is not null drop synonym syn_xxx
    exec('create synonym syn_xxx for sometable')
    SELECT TOP 1 InvalidColumn from syn_xxx
 END TRY
 BEGIN CATCH
     set @returnCode=ERROR_NUMBER()
 END CATCH
 return @returnCode
END     

我的代码是VBA,如下所示。错误集合不包含任何内容,返回值是一个空字符串。

Dim conn_ As ADODB.Connection
Dim cmd As New ADODB.Command
Set conn_ = New ADODB.Connection
conn_.Open dsn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "TestSP"
cmd.ActiveConnection = conn_
cmd.Execute
sql-server vba adodb
1个回答
0
投票

您在dsn中使用什么提供程序?

Private Sub CommandButton1_Click()

    Dim con As New ADODB.Connection
    Dim cmd As New ADODB.Command
    Dim errLoop As ADODB.Error
    Dim i As Integer
    Dim StrTmp As String


    'On Error GoTo AdoError
    On Error Resume Next

    con.ConnectionString = "Provider=SQLNCLI11;" _
             & "Server=(local);" _
             & "Database=master;" _
             & "Integrated Security=SSPI;"

    con.Open

    cmd.ActiveConnection = con
    cmd.CommandType = adCmdStoredProc
    cmd.CommandText = "TestSP"
    cmd.Execute

    MsgBox ("number of errors after procedure 'testproc'  --- " & con.Errors.Count)

    If con.Errors.Count > 0 Then

        i = 1

        ' Process
        StrTmp = StrTmp & vbCrLf & "VB Error # " & Str(Err.Number)
        StrTmp = StrTmp & vbCrLf & "   Generated by " & Err.Source
        StrTmp = StrTmp & vbCrLf & "   Description  " & Err.Description

        ' Enumerate Errors collection and display properties of
        ' each Error object.

        For Each errLoop In con.Errors
            With errLoop
                StrTmp = StrTmp & vbCrLf & "Error #" & i & ":"
                StrTmp = StrTmp & vbCrLf & "   ADO Error   #" & .Number
                StrTmp = StrTmp & vbCrLf & "   Description  " & .Description
                StrTmp = StrTmp & vbCrLf & "   Source       " & .Source
                i = i + 1
            End With
        Next

        MsgBox (StrTmp)

    End If

    cmd.CommandText = "select 10 as test"
    cmd.CommandType = adCmdText
    cmd.Execute
    MsgBox ("number of errors after 'select 10 as test'  --- " & con.Errors.Count)


    ' Close all open objects.
    If con.State = adStateOpen Then
        con.Close
    End If


End Sub
© www.soinside.com 2019 - 2024. All rights reserved.