VBA/SQL Server:如何将成功/错误消息从 db 返回到 vba excel

问题描述

我在我的 excel vba 代码中使用存储过程将数据传递到 sql server 并将返回消息发送回 vba 代码。好吧,我在这个网站和其他网站上的其他问题主题中读了很多,但我找不到这种方法的最佳解决方案。为了给大家更好的想象,我举个例子:

VBA 代码

// defined vba function to return message from database to gui
Public Function fgetMessage() As String
    ' Declare variable and store the data id in the .Tag of userform
    Dim lngVarId As Long
    lngVarId = UserForm1.tbVar.Tag
    
    ' Instance of ADODB.Connection
    Dim oDatabase As clsDatabase
    Set oDatabase = New clsDatabase
    
    ' send sql statement with sproc to sql server and get a return message from database
    Dim oCmd As ADODB.Command
    Set oCmd = New ADODB.Command
    
    With oCmd
        .ActiveConnection = oDatabase.fgetDbConnection()
        .CommandType = adCmdstoredProc
        .CommandText = "dbo.spDeleteProtocolData"
        .Parameters(1) = lngVarId
        
        Dim oRs As ADODB.Recordset
        Set oRs = New ADODB.Recordset
        Set oRs = oCmd.Execute
    End With
    
    fgetDeleteMessage = oCmd.Fields("ReturnMessage") // here I want the string return message
End Function

sql 服务器:

// defined stored procedure in sql server
CREATE PROCEDURE dbo.spDeleteProtocolData
   @VarId AS INT
AS
BEGIN
   SET NOCOUNT ON;

   BEGIN TRY
    BEGIN TRANSACTION
        UPDATE dbo.vProtocolData
        SET StatusId = 0
        WHERE VarId = @VarId
    COMMIT TRANSACTION
   END TRY
   BEGIN CATCH
    -- store error message in log table
    INSERT INTO dbo.Logs (ErrNumber,ErrLine,ErrState,ErrSeverity,ErrSProc,ErrMessage,CreatedBy,CreatedAt)
    SELECT ERROR_NUMBER(),ERROR_LINE(),ERROR_STATE(),ERROR_SEVERITY(),ERROR_PROCEDURE(),ERROR_MESSAGE(),CURRENT_USER,GETDATE()

    ROLLBACK TRANSACTION
   END CATCH
END
GO

有没有人有想法或更好的解决方案来处理 vba excel 和 sql server 数据库间的返回消息?

解决方法

您可以使用输出参数:

Dim B As Boolean
Dim C As ADODB.Command
Dim I As Long
Dim P As ADODB.Parameter
Dim V As Variant

   Set C = New ADODB.Command
   C.ActiveConnection = glob_CONNECT
   C.CommandType = adCmdStoredProc
   C.CommandText = X.SQL_Name
   
   ' bind Inputparameter
   If X.NInParams > 0 Then
      For I = 1 To X.NInParams Step 1
         Set P = C.CreateParameter(X.InParam(I).SQL_Name,_
                                   X.InParam(I).ADODB_Type,_
                                   adParamInput,_
                                   X.InParam(I).SQL_Size,_
                                   X.InParam(I).SQL_Value)
         C.Parameters.Append P
      Next
   End If
   
   ' bind Outputparameter
   If X.NOutParams > 0 Then
      For I = 1 To X.NOutParams Step 1
         Set P = C.CreateParameter(X.OutParam(I).SQL_Name,_
                                   X.OutParam(I).ADODB_Type,_
                                   adParamOutput,_
                                   X.OutParam(I).SQL_Size)
         C.Parameters.Append P
      Next
   End If
   
   ' Execute SP (Errors are possible!)
   On Error GoTo 0
   On Error Resume Next
   C.Execute
   
   ' Error?
   If Err.Number <> 0 Then
      SQL_EXEC = False
      Exit Function
   End If

   ' Fetch Output
   If X.NOutParams > 0 Then
      For I = 1 To X.NOutParams Step 1
         V = VNormExec(C.Parameters(X.OutParam(I).SQL_Name),X.OutParam(I).SQL_Type)
         X.OutParam(I).SQL_Value = V
      Next
   End If