从 VBA 执行 SQL Server 存储过程并检索所有消息和结果集

2023-12-01

我希望能够从 MS Access VBA 执行 SQL Server 存储过程,这样我就可以读取 (1) 所有结果结果集,而不仅仅是第一个结果集; (2) 由 PRINT 语句或类似语句产生的任何消息。

我有一个带有一个输入参数的测试存储过程,它会生成 3 个不同的结果集和大约 90 条消息。它调用多个子存储过程,我可以从 SSMS 完美地执行它,但(对我来说)不清楚如何最好地从 Access VBA 执行它。到目前为止我已经尝试过以下操作:

  1. 道。使用 SQL 传递查询,我可以在 DAO 中获得很多我想要的东西,尽管它有点笨拙。它返回 3 个结果集中的第一个作为记录集,通过使用 LogMessages 属性,我可以获得一个包含发出的消息的表(“Admin – NN”)。

  2. 阿多。使用 Connection 和 Command 对象,我可以获得表示存储过程中第一个结果集的单个记录集。然而,我似乎无法说服它产生除了只进记录集之外的任何东西。关于消息,在某一时刻,所有消息(至少是我预期的大约 150 条中的前 127 条)都将进入连接的错误集合 (!),但是当我将数量减少到大约 90 条时,没有一条消息出现在我能找到的任何地方。

正如我一开始所说,我真正想要的是输出所有结果集, 加上消息。这可能吗?

以下是我当前用于执行存储过程的例程的列表:

Function ExecuteStoredProcedureADO(SPName As String, Connect As String, ReturnsRecords As Boolean, _
   ParamArray Params() As Variant) As ADODB.Recordset
   ' v1.0 2018/06/26
   ' execute stored procedure SPName on a SQL Server database specified by the string in Connect

   Dim strErr As String
   Dim i As Integer
   Dim lngRecsAffected As Long

   Dim cnn As ADODB.Connection
   Dim cmd As ADODB.Command
   Dim errCurr As ADODB.Error
   Dim rst As ADODB.Recordset

   On Error GoTo Catch
   Set ExecuteStoredProcedureADO = Nothing

   Set cnn = New ADODB.Connection
   cnn.Errors.Clear
   cnn.mode = adModeRead
   cnn.CommandTimeout = 300
   cnn.Open Connect

   Set cmd = New ADODB.Command
   With cmd
      .ActiveConnection = cnn
      .CommandText = SPName
      .CommandType = adCmdStoredProc

      For i = 0 To UBound(Params) Step 4
         .Parameters.Append .CreateParameter(Params(i), Params(i + 1), adParamInput, Params(i + 2), Params(i + 3))
      Next i
      Set rst = New ADODB.Recordset
      rst.CursorType = adOpenStatic
      If ReturnsRecords Then
         '''Set rst = .Execute(lngRecsAffected)
         rst.Open cmd, , adOpenStatic, adLockReadOnly
      Else
         Set rst = .Execute(, , adExecuteNoRecords)
      End If
   End With
   If ReturnsRecords Then Set ExecuteStoredProcedureADO = rst

Final:
   On Error Resume Next
   If Len(strErr) > 0 Then Call AppendMsg(strErr)
   Set rst = Nothing
   Set cmd = Nothing
   Exit Function

Catch:
   If cnn.Errors.Count > 0 Then
      With cnn
         For Each errCurr In cnn.Errors
            strErr = strErr & "Error " & errCurr.Number & ": " & errCurr.Description _
               & " (" & errCurr.Source & ")" & vbCrLf
         Next errCurr
         strErr = Left(strErr, Len(strErr) - 2) ' truncate final CRLF
      End With
   Else
      strErr = "Error " & Err.Number & ": " & Err.Description & " (" & Err.Source & ")"
   End If
   MsgBox strErr, vbOKOnly, gtitle
   Resume Final

End Function

附录:关于多个结果集,我希望http://msdn.microsoft.com/en-us/library/ms677569%28VS.85%29.aspx会有一定的帮助。


为了无耻地利用@Erik,你想创建一个新的类来处理你的处理。就像是cProcedureHandler。在这个类中,您需要声明一个ADODB.Connection对象使用WithEvents关键词:

Dim WithEvents cn As ADODB.Connection

然后,你需要写一个InfoMessage事件处理程序将处理多个打印语句。有关信息InfoMessage可以找到事件here,并使用连接的Errors可以找到合集here。所以你最终会得到这样的结果:

  Private Sub cn_InfoMessage(ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
     Dim err As ADODB.Error

     Debug.Print cn.Errors.Count & " errors"

     For Each err In cn.Errors
        ' handle each error/message the way you need to.
        Debug.Print err.Description
     Next err
  End Sub

由于您已经处理了处理多条消息的代码,现在您只需要处理多个记录集,这在您提供的链接中得到了很好的解释。我注意到的一件事是示例链接使用rs is nothing作为检查何时没有更多记录集,这对我不起作用。我不得不使用 rsState财产。所以我最终得到了这个:

  Public Sub testProcedure()
     Dim cmd As ADODB.Command
     Dim rs As ADODB.Recordset
     Dim recordSetIndex As Integer

     Set cn = modData.getConnection

     Set cmd = New ADODB.Command
     cmd.ActiveConnection = cn
     cmd.CommandType = adCmdStoredProc
     cmd.CommandText = "dbo.sp_foo"

     Set rs = cmd.Execute

     recordSetIndex = 1

     Do Until rs.State = ObjectStateEnum.adStateClosed
        Debug.Print "contents of rs #" & recordIndex
        Do Until rs.EOF
           Debug.Print rs.Fields(0) & rs.Fields(1)
           rs.MoveNext
        Loop

        Set rs = rs.NextRecordset
        recordSetIndex = recordIndex + 1
     Loop

     cn.Close
     Set rs = Nothing
     Set cn = Nothing
     Set cmd = Nothing

  End Sub

然后,当您准备好从 VBA 运行 SP 时,只需执行以下操作:

set obj = new cProcedureHandler
obj.testFooProcedure

另一件事(您可能已经这样做了):确保 SQL Server 中的实际存储过程设置了 nocount。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 VBA 执行 SQL Server 存储过程并检索所有消息和结果集 的相关文章

  • 如何将 nvarchar 解码为文本(SQL Server 2008 R2)?

    我有一个 SQL Server 2008 R2 表nvarchar 4000 field 存储该表的数据如下所示 696D616765206D61726B65643A5472 or 303131 011 我看到每个字符都编码为十六进制 我如
  • 如何在SQL Server中创建SYS模式的表?

    可以在 SQL Server 2008 sys 架构中创建表吗 我知道可以将表标记为系统 但不能更改架构 有什么窍门吗 您无法将自己的对象添加到 sys 架构中 无法在 sys 架构中创建用户定义的对象 盖尔 埃里克森 MS SQL Ser
  • 使用VBA复制垂直列并沿对角线粘贴

    我有一列数据 我们称之为 A 列 其中有 35 行数据 如何在此列上循环 然后将每个数据点粘贴到另一张工作表中 同时为每个循环循环增加列和行 换句话说 我寻求对角粘贴在第二张纸中 有没有一种简单的方法可以在 VBA 中执行此类操作 不要循环
  • 存储过程 - 使用 NOT IN where 子句执行查询

    我有一个存储过程 Create PROCEDURE abc sRemovePreviouslySelectedWhereClause nvarchar max AS BEGIN SELECT FROM table WHERE nId NOT
  • CROSS APPLY 不适用于 SQL SERVER 2000?

    如何在 SQL Server 2000 中使用与 CROSS APPLY 等效的功能 我有一个函数返回传递的 id 的顶级父级 ALTER Function dbo fn GetTopParentRiskCategory RctId int
  • 如何处理用户界面中的数据库约束违规?

    我们使用存储过程在数据库中实现大部分业务规则 我永远无法决定如何最好地将数据约束违规错误从数据库传递回用户界面 我所说的约束更多地与业务规则相关 而不是与数据完整性相关 例如 诸如 无法插入重复的键行 之类的数据库错误与业务规则 不能有多个
  • SQL Server 2008 R2 的 Try_Convert

    我正在使用 SQL Server 2008 R2 并且有一个VARCHAR我想要转换为的列DECIMAL 28 10 using CONVERT 但其中许多行的格式错误 因此无法将它们解析为数字 在这种情况下 我只想通过将结果设置为 0 或
  • Visual Studio SSDT Data Compare如何比较单个数据库中的两个表

    尝试在 SSDT 中做一些简单的数据比较 但事实证明有点困难 在一个数据库中 我有两个要比较的表 这些表具有相同的架构 只是表名不同 我只是想看看这个工具是否能给我一个很好的方法来比较两者的数据 I e tblOutput tblOutpu
  • SQL SERVER 中的排序依据和大小写

    我需要在存储过程中按功能排序 一个值被发布到网络服务 并且基于该值我必须以某种方式对结果进行排序 即 当 ColName 按 ColName 发布订单时 当 ColName2 由 ColName2 发布订单时 我正在研究使用 Case 但出
  • 表名搜索

    我使用以下命令在特定数据库的存储过程中搜索字符串 USE DBname SELECT Name FROM sys procedures WHERE OBJECT DEFINITION OBJECT ID LIKE xxx 修改上面的内容是否
  • 使用 WHILE 创建虚拟数据

    我尝试使用 a 在表中插入一些虚拟数据WHILE 但它运行得非常非常慢 我在想也许我写的代码不正确 你能看一下并确认一下吗 Insert dummy data DECLARE i int Content int SET i 5001 WHI
  • 无法在我的抓取工具中设置超时选项以防止无限循环

    我已经使用 IE 在 vba 中编写了一个脚本 在其搜索框中的网页中启动搜索 通过点击搜索按钮根据搜索填充结果 网页加载它是searchbox几秒钟后它就会打开 但是 我的下面的脚本可以处理这个障碍并以正确的方式执行搜索 现在 我有一个稍微
  • 使用 VBA 的下拉菜单

    我需要使用 VBA 从下拉菜单中选择特定选项 我怎样才能做到这一点 链接到我们试图从中提取的网页 IE document getElementsByName down count click 我尝试过的代码 Full Module Priv
  • 如何从经典 ASP 读取 SQL Always-加密列

    我维护一个经典的 ASP 应用程序 是的 我知道 我们正在开发它 并且需要访问 SQL 2017 中的 Always Encrypted 列 我已经导入了证书并在 SSMS 和 PowerShell 中进行了测试 这很有效 我在 ASP 中
  • 如何在VBA编辑器中跳转到行号?

    我在 Office 2010 中使用 VBA 在顶部 有一个带有行号和列号的框 例如 Ln 1480 Col 17 有没有办法在代码编辑中 而不是在执行中 直接跳转到另一个行号 就像我使用的那样Ctrl G在记事本中 这个MSDN答案 ht
  • VBA Shell 并等待退出代码

    我正在打包一个办公应用程序 VBA 它调用 C 控制台应用程序来执行应用程序 大型模拟程序 的一些繁重工作 我希望能够让 VBA 应用程序等待控制台应用程序完成并从控制台应用程序检索退出代码 我已经能够做到前者 但尚未能够从应用程序中检索退
  • sql查询将两列与一列连接起来

    我在 MS Access 2010 中有 2 个表 如下所示 USERS u id u name LOAN l id l from ref users u id l to ref users u id l amount Users u id
  • 如何在 SQL Server 中的特定字符后分割字符串并将该值更新到特定列

    我有包含数据的表格1 1 to 1 20在一列中 我想要值 1 到 20 即 前斜杠 之后的值更新到 SQL Server 中同一表中的其他列 Example 专栏有价值1 1 1 2 1 3 1 20新列值1 2 3 20 也就是说 我要
  • PDO SQLSRV 和 PDO MySQL 在获取 int 或 float 时返回字符串

    当您获取时 PDO MS SQL Server 和 PDO MySQL 都会返回一个字符串数组 即使列的 SQL 类型本应是数字类型 例如 int 或 float 我设法解决了这个问题 但我想了解为什么它们一开始就这样设计 是不是因为PDO
  • 如何找到特定程序的安装目录?

    我已经成功地编写了一些用于工作的 VBA 宏 这些宏基本上创建了一个数据文件 将其提供给一个程序并对该程序的输出进行后处理 我的问题是程序安装路径是硬编码在宏中的 并且安装在我同事的计算机上可能会有所不同 我首先想到的是 我可以从每个人那里

随机推荐

  • 从 Matlab 轮廓函数中选择等值线

    Matlab 轮廓函数 和 imcontour 绘制矩阵不同级别的等值线 我想知道 如何操纵该函数的输出以便接收每个轮廓的所有 x y 坐标以及级别 如何使用输出 C h 轮廓 来实现上述任务 另外 我对操纵底层网格不感兴趣 它是一个连续函
  • 当输入获得焦点时 CSS 改变图标颜色

    我希望用户图标和锁定图标在输入聚焦时改变颜色 但我不知道该怎么做 有人可以帮助我吗 我希望图标颜色为 c0392b div class input icons span class fa fa user span div
  • 函数声明 - 函数表达式 - 作用域

    在javascript中 函数声明和函数表达式在作用域方面有什么区别 函数声明意味着我们正在污染全局空间 函数表达式的情况是一样的吗 函数声明 function sum logic goes here 函数表达式 var sum funct
  • HTML 选择和文本输入

    我们都见过无数的表单实例 其中一个选择下拉菜单的选项之一为 其他 选择该选项后 我们会看到一个输入文本框 一直隐藏 要求我们输入输入内容 有没有更好的方法来实现这个 有没有插件可以让我做得更好 或者标准 HTML 元素就足够了 可能对选择标
  • 如何将 URL 参数列表字符串分解为成对的 [key] => [value] 数组? [复制]

    这个问题在这里已经有答案了 可能的重复 将查询字符串解析为数组 如何分解字符串 例如 a 1 b 2 c 3 从而变成 Array a gt 1 b gt 2 c gt 3 使用常规的explode 函数定界于 将分隔参数但不在 key g
  • xs:key,为什么当键值不是键引用的成员时验证会通过?

    我有兴趣在我的 Xsd 中定义一个关键约束 据我了解 使用xs key应该将使用的值限制为引用值列表的成员 假设我们使用样本 Xsd
  • Scala:有没有办法像在 Java 中一样使用 PriorityQueue?

    我有一个类 我想在 scala collection mutable PriorityQueue 中使用 但我不想仅出于此目的将其设为 Ordered A 我不认为我想要使用的 PriorityQueue 排序是类的自然排序 class M
  • 为什么STL容器没有虚拟析构函数?

    有谁知道为什么STL容器没有虚拟析构函数 据我所知 唯一的好处是 它通过一个指针 指向虚拟方法表 减少实例的大小 并且 它使破坏和建设速度更快一些 缺点是以通常的方式对容器进行子类化是不安全的 我的问题可以重新表述的另一种方式是 为什么 S
  • 获取列类型的SQL语句

    有没有可以返回表中列的类型的SQL语句 In ISO SQL i e most RDBMS today you can use the INFORMATION SCHEMA COLUMNS view which SQL Server sup
  • Python argv 采用通配符路径

    我运行我的脚本doc1 png作为第一个参数 但它被转换为doc1 image1 png 我怎样才能让Python看到确切的参数 img list print sys argv 1 x sys argv 1 img list img for
  • 调用方法后如何在标准输出中写入(自动执行通知系统(Iphone))

    我正在尝试使用自动通知系统 Iphone https github com simonwhitaker PyAPNs 当您想要发送通知时 您可以调用 apns gateway server send notification key Pay
  • bluebirdjs 承诺包裹在 for 循环中

    我有很多函数用于向我的服务提供数据 我想循环遍历它们中的每一个 并在其中一个返回所需结果时立即停止 如果第一个有效 那很好 如果有异常或数据无效 我想转到下一个 依此类推 我怎样才能实现这个目标 我有以下代码 handleData func
  • Facebook“赞”按钮回调

    我对实现 facebook 喜欢 按钮感兴趣 但我想知道哪些用户正在单击此按钮 以便我可以从中获取一些有用的信息 据我所知 Facebook 让我们对谁在点击什么一无所知 有人知道如何跟踪哪个用户点击了特定产品的 喜欢 按钮吗 更新 赞 按
  • 如何将对象存储在 firebase cloud function RAM 中?

    我的应用程序需要在处理用户的请求之前构建几个大型哈希图 理想情况下 我想将这些哈希图存储在机器的内存中 这意味着它永远不需要进行任何昂贵的处理 并且可以快速处理任何传入的请求 但这对于 Firebase 不起作用 因为用户有可能触发一个新实
  • 将运行 EXE 的当前 Windows 用户替换为另一个用户

    假设我构建了一个从网络文件夹读取文件的 Windows 应用程序 网络折叠限制只有一个用户 fooUser 的访问 该应用程序安装在网络上的多台计算机上 我需要将当前用户替换为 fooUser 以便能够通过代码访问网络文件夹上的文件 这是一
  • 如何以字幕方式输出字符串?

    我希望能够输入一个字符串 带空格 并将其显示为移动符号 例如 Input Hello World 5 This signifies the number of characters the sign can hold Output Sign
  • arr.sort(key=lambda x: (x[0],-x[1])) 是什么意思?

    gt gt gt arr 4 5 4 6 6 7 2 3 1 1 gt gt gt arr sort key lambda x x 0 statement 1 gt gt gt arr 1 1 2 3 4 5 4 6 6 7 gt gt g
  • CSS 在背景图像上模糊,但在内容上不模糊 [重复]

    这个问题在这里已经有答案了 I did 这个例子 我试图模糊背景图像 但主要内容也模糊了 span 如何在不模糊内容的情况下模糊背景 jsfiddle blur bgimage overflow hidden margin 0 text a
  • 如何用mongoosastic+AJAX进行即时搜索?

    我已经成功配置了 mongoosastic 我尝试搜索并且工作正常 但是当涉及到前端时我不太确定如何实现这一点 我尝试了很多方法但无法想出一个好的解决方案 这是代码 For the Search API router post api se
  • 从 VBA 执行 SQL Server 存储过程并检索所有消息和结果集

    我希望能够从 MS Access VBA 执行 SQL Server 存储过程 这样我就可以读取 1 所有结果结果集 而不仅仅是第一个结果集 2 由 PRINT 语句或类似语句产生的任何消息 我有一个带有一个输入参数的测试存储过程 它会生成