Aracılığıyla paylaş


ADO ile SQL Server Saklı Yordamlarındaki değerleri alma

Bu makalede, ADO ile SQL Server Saklı Yordamlarındaki değerlerin nasıl alınıyor olduğu gösterilmektedir.

Özgün ürün sürümü: SQL Server
Özgün KB numarası: 194792

Özet

ActiveX Veri Nesneleri (ADO) aracılığıyla SQL Server saklı yordamlarından değer almaya RAISERROR/PRINT/RETURN çalışırken dikkate alınması gereken önemli sorunlar vardır. Üç sorun şunlardır:

  • RAISERROR SQL Server'daki deyimlerin önem düzeyi 11-18 olmalıdır.

  • SQL Server'daki PRINT deyimleri de ADO hataları koleksiyonunu doldurabilir. Ancak, PRINT deyimleri önem düzeyi sıfır (0) olduğundan, Errors koleksiyonu aracılığıyla ADO ile bir PRINT deyimi almak için saklı yordamda en az RAISERROR bir deyim gereklidir.

  • Saklı yordamdaki RETURN değerleri en az bir sonuç kümesiyle ilişkilendirilmelidir.

Daha Fazla Bilgi

Aşağıdaki kod örneği, birden çok sonuç kümesi döndüren bir SQL Server saklı yordamından ayrıntılara erişmek RAISERROR/PRINT/RETURN için ADO Hataları koleksiyonuna göz atmayı gösterir:

  1. 4. adımda ADO örneği için kullanılan saklı yordamı oluşturmak üzere Pubs veritabanı oluşturduktan sonra SQL Server Management Studio (SSMS) penceresine aşağıdaki kodu yapıştırın ve yürütün:

    use pubs
    GO
    
    if exists (select * from sysobjects where id = object_id('dbo.ADOTestRPE') and sysstat & 0xf = 4)
        drop procedure dbo.ADOTestRPE
    GO
    
    create procedure ADOTestRPE
     (
         @SetRtn INT=0 OUTPUT,
         @R1Num INT=1,
         @P1Num INT=1,
         @E1Num INT=1,
         @R2Num INT=2,
         @P2Num INT=2,
         @E2Num INT=2
     )
     AS
     DECLARE @iLoop INT
     DECLARE @PrintText VARCHAR(255)
     DECLARE @iErrNum INT
    
    /* Check for no Resultsets - needed to get the RETURN value back */ 
     IF @R1Num + @R2Num = 0 SELECT NULL
    
    /* Resultset 1 ******************************* */ 
    
    IF @R1Num > 0
        BEGIN
            SET ROWCOUNT @R1Num
            SELECT 'Resultset 1' RsNum, Title
            FROM Pubs..Titles
            SET ROWCOUNT 0
        END
    
    /* Must raise a default error context in which to return the PRINT */ 
     /* statement */ 
     /* (if none present) since PRINT statements are a severity level of */ 
     /*0. */ 
    IF (@P1Num > 0) AND (@E1Num = 0) RAISERROR ("RAISERROR.PError1", 11, 2)
    
    IF @P1Num > 0
        BEGIN
            SELECT @iLoop = 0
            WHILE @iLoop < @P1Num
            BEGIN
            SELECT @iLoop = @iLoop + 1
            SELECT @PrintText = 'PRINT.Resultset.1: Line ' +
            CONVERT(char(2), @iLoop)
            PRINT @PrintText
        END
    END
    
    IF @E1Num > 0
        BEGIN
            SELECT @iLoop = 0
            WHILE @iLoop < @E1Num
            BEGIN
            SELECT @iLoop = @iLoop + 1
            SELECT @iErrNum = @iLoop + 201000
            RAISERROR ("RAISERROR.Resultset.1", 11, 2)
        END
    END
    
    /* Resultset 2 ******************************* */ 
    
    IF @R2Num > 0
        BEGIN
            SET ROWCOUNT @R2Num
            SELECT 'Resultset 2' RsNum, Title
            FROM Pubs..Titles
            SET ROWCOUNT 0
        END
    
    /* Must raise a default error context in which to return the PRINT */ 
    /* statement */ 
    /* (if none present) since PRINT statements are a severity level of */ 
    /* 0. */ 
    IF (@P2Num > 0) AND (@E2Num = 0) RAISERROR ("RAISERROR.PError2",11, 2)
    
    IF @P2Num > 0
     BEGIN
     SELECT @iLoop = 0
     WHILE @iLoop < @P2Num
     BEGIN
     SELECT @iLoop = @iLoop + 1
     SELECT @PrintText = 'PRINT.Resultset.2: Line ' +
     CONVERT(char(2), @iLoop)
     PRINT @PrintText
     END
     END
    
    IF @E2Num > 0
        BEGIN
            SELECT @iLoop = 0
            WHILE @iLoop < @E2Num
            BEGIN
            SELECT @iLoop = @iLoop + 1
    
            SELECT @iErrNum = @iLoop + 202000
            RAISERROR ("RAISERROR.Resultset.2", 11, 2)
        END
    END
    
    /* Return & Output ************************************ */ 
    
    select @SetRtn = -1
    RETURN @SetRtn
    GO
    
    
  2. Visual Basic'te Standart .EXE projesi oluşturun. Form1 varsayılan olarak oluşturulur.

  3. Proje menüsünden Başvurular'ı ve ardından Microsoft ActiveX Veri Nesneleri Kitaplığı'nı seçin.

    Not

    Kodun düzgün çalışması için ADO sürüm 2.0 veya üzerini kullanmanız gerekir. Web'de en son Microsoft Veri Erişim Bileşenleri (MDAC) bileşenlerini şu konumdan edinebilirsiniz: MDAC.

  4. Forma bir Komut düğmesi yerleştirin ve ardından formun Genel Bildirimler bölümüne aşağıdaki kodu yapıştırın. Ortamınız için veritabanı bağlantı dizesini değiştirmeniz gerekebilir.

    'This Code demonstrates RAISERROR/PRINT/RETURN values with ADO and
    'multiple resultsets.
    
    Sub CreateParms()
    
    Dim ADOCmd As New ADODB.Command
    Dim ADOPrm As New ADODB.Parameter
    Dim ADOCon As ADODB.Connection
    Dim ADORs As ADODB.Recordset
    Dim sParmName As String
    Dim strConnect As String
    Dim rStr As String
    
    On Error GoTo ErrHandler
    
    strConnect = "driver={SQL
    Server};server=(local);uid=sa;pwd=;database=pubs"
    
    Set ADOCon = New ADODB.Connection
    With ADOCon
    .Provider = "MSDASQL"
    .CursorLocation = adUseServer 'Must use Server side cursor.
    .ConnectionString = strConnect
    .Open
    End With
    
    Set ADOCmd.ActiveConnection = ADOCon
    With ADOCmd
    .CommandType = adCmdStoredProc
    .CommandText = "ADOTestRPE"
    End With
    
    'Parameter 0 is the stored procedure Return code.
    sParmName = "Return"
    Set ADOPrm = ADOCmd.CreateParameter(sParmName, adInteger, _
    adParamReturnValue, , 0)
    ADOCmd.Parameters.Append ADOPrm
    ADOCmd.Parameters(sParmName).Value = -1
    
    'Parameter 1 is the setting for the stored procedure Output
    ' parameter.
    sParmName = "Output"
    Set ADOPrm = ADOCmd.CreateParameter(sParmName, adInteger, _
    adParamOutput)
    ADOCmd.Parameters.Append ADOPrm
    ADOCmd.Parameters(sParmName).Value = 999
    
    'Parameter 2
    sParmName = "R1Num" 'Number of rows to return in Resultset 1.
    Set ADOPrm = ADOCmd.CreateParameter(sParmName, adInteger, _
    adParamInput)
    ADOCmd.Parameters.Append ADOPrm
    ADOCmd.Parameters(sParmName).Value = 1
    
    'Parameter 3
    sParmName = "P1Num" 'Number of PRINT statements in Resultset 1.
    Set ADOPrm = ADOCmd.CreateParameter(sParmName, adInteger, _
    adParamInput)
    ADOCmd.Parameters.Append ADOPrm
    ADOCmd.Parameters(sParmName).Value = 0
    
    'Parameter 4
    sParmName = "E1Num" 'Number of RAISERROR statements in Resultset
    '1.
    Set ADOPrm = ADOCmd.CreateParameter(sParmName, adInteger, _
    adParamInput)
    ADOCmd.Parameters.Append ADOPrm
    ADOCmd.Parameters(sParmName).Value = 0
    
    'Parameter 5
    sParmName = "R2Num" 'Number of rows to return in Resultset 2.
    Set ADOPrm = ADOCmd.CreateParameter(sParmName, adInteger, _
    adParamInput)
    ADOCmd.Parameters.Append ADOPrm
    ADOCmd.Parameters(sParmName).Value = 2
    
    'Parameter 6
    sParmName = "P2Num" 'Number of PRINT statements in Resultset 2.
    Set ADOPrm = ADOCmd.CreateParameter(sParmName, adInteger, _
    adParamInput)
    ADOCmd.Parameters.Append ADOPrm
    ADOCmd.Parameters(sParmName).Value = 0
    
    'Parameter 7
    sParmName = "E2Num" 'Number of RAISERROR statements in Resultset
    ' 2.
    Set ADOPrm = ADOCmd.CreateParameter(sParmName, adInteger, _
    adParamInput)
    ADOCmd.Parameters.Append ADOPrm
    ADOCmd.Parameters(sParmName).Value = 0
    
    Set ADORs = ADOCmd.Execute
    
    Do While (Not ADORs Is Nothing)
        If ADORs.State = adStateClosed Then Exit Do
        While Not ADORs.EOF
            For i = 0 To ADORs.Fields.Count - 1
            rStr = rStr & " : " & ADORs(i)
        Next i
        Debug.Print Mid(rStr, 3, Len(rStr))
        ADORs.MoveNext
        rStr = ""
        Wend
        Debug.Print "----------------------"
        Set ADORs = ADORs.NextRecordset
    Loop
    
    Debug.Print "Return: " & ADOCmd.Parameters("Return").Value
    Debug.Print "Output: " & ADOCmd.Parameters("Output").Value
    
    GoTo Shutdown
    
    ErrHandler:
    Call ErrHandler(ADOCon)
    Resume Next
    
    Shutdown:
    Set ADOCmd = Nothing
    Set ADOPrm = Nothing
    Set ADORs = Nothing
    Set ADOCon = Nothing
    
    End Sub
    
    Private Sub Command1_Click()
    
    Call CreateParms
    
    End Sub
    
    Sub ErrHandler(objCon As Object)
    
    Dim ADOErr As ADODB.Error
    Dim strError As String
    
    For Each ADOErr In objCon.Errors
        strError = "Error #" & ADOErr.Number & vbCrLf & ADOErr.Description _
        & vbCr & _
        " (Source: " & ADOErr.Source & ")" & vbCr & _
        " (SQL State: " & ADOErr.SQLState & ")" & vbCr & _
        " (NativeError: " & ADOErr.NativeError & ")" & vbCr
        If ADOErr.HelpFile = "" Then
            strError = strError & " No Help file available" & vbCr & vbCr
        Else
            strError = strError & " (HelpFile: " & ADOErr.HelpFile & ")" _
            & vbCr & _
            " (HelpContext: " & ADOErr.HelpContext & ")" & _
            vbCr & vbCr
        End If
        Debug.Print strError
    Next
    
    objCon.Errors.Clear
    
    End Sub
    
  5. Saklı yordam tarafından oluşturulan ve ADO aracılığıyla döndürülen deyimlerin ve/veya RAISERROR deyimlerin PRINT sayısını değiştirmek için parametrelerin değerini iki ile yedi arasında değiştirin. Visual Basic kod örneğini yeniden çalıştırın ve ve PRINT deyimlerinin ADO hataları koleksiyonu aracılığıyla döndürüldüğünü RAISERROR unutmayın. Farklı sonuç kümelerine sahip farklı deyim birleşimleriyle PRINT/RAISERROR deneme yapmak için değerleri değiştirin. Özel durumlar için belirli geçici çözümler için SQL saklı yordamlarına bakın.

Saklı yordamla ADO'da RETURN değeri almak için en az bir sonuç kümesi olmalıdır. Bu soruna geçici bir çözüm olarak, hiçbir sonuç kümesi belirtilmediğinde (ADO örnek kodunda) saklı yordam, ADO'ya null sonuç kümesi döndürerek RETURN değerini dolduran bir SELECT NULL çalıştırır. Buna ek olarak, deyim ve RAISERROR deyim birleşimi PRINT belirtme sorununa geçici bir çözüm olarak, ADO aracılığıyla deyimi döndürmek PRINT için bir bağlam sağlamak üzere varsayılan RAISERROR deyimler oluşturulur. Yalnızca 11-18 önem düzeyleri ADO hataları koleksiyonu aracılığıyla geri döndüğünden, deyimleri saklı yordamda gösterilen biçimde kodlamalısınız RAISERROR .

Başvurular

RAISERROR (Transact-SQL)