【问题标题】:ADO Connection.Execute keeps returning a closed recordsetADO Connection.Execute 不断返回一个关闭的记录集
【发布时间】:2018-01-30 01:48:56
【问题描述】:

我正在尝试使用 ADO 对象将传递给 SQL 服务器的 sql 命令的结果返回到 Excel 中,但我的 Recordset 不断返回关闭/空。我的猜测是我的 sql 语句没有返回任何东西——尽管我认为它应该返回一条记录。

我正在运行的 SQL 是一个 530 行的野兽,但它归结为一个 MERGE 语句,该语句应该将结果转储到表 var 中,然后从中进行选择。这个 select 语句就是我想要返回到 ADO 记录集中的语句。

这是我正在使用的通用 SQL 语句:

     MERGE ldw_plan_working AS target 
 USING source 
 ON target.DT_Code = source.DT_Code 
    AND target.Country = source.Country 
    AND target.Channel = source.Channel 
    AND target.HierarchyID = source.HierarchyID 
    AND target.lifecycle = source.lifecycle 
     WHEN MATCHED 
     THEN UPDATE SET 
                     [Sales_TOT_Local] = source.[Sales_TOT_Local], 
                     [Sales_TOT_USD] = source.[Sales_TOT_USD], 
                     [Sales_TOT_CAD] = source.[Sales_TOT_CAD], 
                     [Sales_CLR_Local] = source.[Sales_CLR_Local], 
                     [Sales_CLR_USD] = source.[Sales_CLR_USD], 
                     [Sales_CLR_CAD] = source.[Sales_CLR_CAD], 
                     [PM_TOT_Local] = source.[PM_TOT_Local], 
                     [PM_TOT_USD] = source.[PM_TOT_USD], 
                     [PM_TOT_CAD] = source.[PM_TOT_CAD], 
                     [PM_CLR_Local] = source.[PM_CLR_Local], 
                     [PM_CLR_USD] = source.[PM_CLR_USD], 
                     [PM_CLR_CAD] = source.[PM_CLR_CAD], 
                     [Sales_TOT_U] = source.[Sales_TOT_U], 
                     [Sales_CLR_U] = source.[Sales_CLR_U], 
                     [Receipt_USD] = source.[Receipt_USD], 
                     [Receipt_U] = source.[Receipt_U] 
     WHEN NOT MATCHED 
     THEN 
       INSERT([DT_Code], 
              [Country], 
              [Channel], 
              [HierarchyID], 
              [Lifecycle], 
              [Sales_TOT_Local], 
              [Sales_TOT_USD], 
              [Sales_TOT_CAD], 
              [Sales_CLR_Local], 
              [Sales_CLR_USD], 
              [Sales_CLR_CAD], 
              [PM_TOT_Local], 
              [PM_TOT_USD], 
              [PM_TOT_CAD], 
              [PM_CLR_Local], 
              [PM_CLR_USD], 
              [PM_CLR_CAD], 
              [Sales_TOT_U], 
              [Sales_CLR_U], 
              [Receipt_USD], 
              [Receipt_U]) 
       VALUES 
 (source.[DT_Code], 
  source.[Country], 
  source.[Channel], 
  source.[HierarchyID], 
  source.[Lifecycle], 
  source.[Sales_TOT_Local], 
  source.[Sales_TOT_USD], 
  source.[Sales_TOT_CAD], 
  source.[Sales_CLR_Local], 
  source.[Sales_CLR_USD], 
  source.[Sales_CLR_CAD], 
  source.[PM_TOT_Local], 
  source.[PM_TOT_USD], 
  source.[PM_TOT_CAD], 
  source.[PM_CLR_Local], 
  source.[PM_CLR_USD], 
  source.[PM_CLR_CAD], 
  source.[Sales_TOT_U], 
  source.[Sales_CLR_U], 
  source.[Receipt_USD], 
  source.[Receipt_U] 
 ) 
 OUTPUT $action 
        INTO @tableVar;
INSERT INTO @tableVar(MergeAction) 
VALUES('nothing'); 
SELECT [UPDATE], 
       [INSERT], 
       [DELETE] 
FROM @tableVar PIVOT(COUNT(MergeAction) FOR MergeAction IN([UPDATE], 
                                                       [INSERT], 
                                                       [DELETE], 
                                                       [nothing])) AS piv;

而vba函数长这样:

Public Function Run_SQL_Cmd(sql As String)
Dim cnn As Object
Dim cmd As Object
Dim rs As Object
Dim recordsAffected As Integer

Set cnn = CreateObject("ADODB.Connection")
Set cmd = CreateObject("ADODB.Command")
Set rs = CreateObject("ADODB.Recordset")

cnn.Open strBEConnection
cnn.CommandTimeout = 0

With cmd
    .ActiveConnection = cnn
    .CommandText = sql
    .CommandType = 1
    Set rs = .Execute
End With

'... do stuff with the recordset

rs.Close
cnn.Close
Set cnn = Nothing
Set rs = Nothing

End Function

rs 总是以 0 字段计数、已关闭的记录集返回,我无能为力。但是当我直接在 SQL Server 中运行相同的 sql 时,显然我确实得到了最终选择语句的结果。有人知道我在这里做错了什么吗?

提前致谢

【问题讨论】:

  • 看来需要用sub代替函数。
  • strBEConnection 未定义。
  • 对不起,这是一个设置为数据库连接字符串的常量。这些都不是任何数据库连接问题。

标签: sql sql-server excel vba


【解决方案1】:

好吧,我想通了。当命令文本中有多个 SQL 语句时,您需要在 SQL 语句中以“SET NOCOUNT ON;”开头。这将使服务器返回最终选择语句的结果。非常烦人的简单修复。

【讨论】:

    猜你喜欢
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-08
    相关资源
    最近更新 更多