使用CTE的Excel VBA ADODB sql查询不返回任何记录

时间:2017-03-01 01:56:13

标签: vba sql-server-2008-r2

这是我关于Stack Overflow的第一个问题。我从这个网站上学到了很多,但是我找不到我遇到的问题的答案。

我有一个在SQL Server 2008 R2管理工作室中运行的SQL查询,但是当我在EXCEL 2013中使用vba查询它时它不起作用。该查询包含一个公用表表达式,并且它不会将任何记录返回到我的记录集。

SQL查询是:

WITH cte AS 
( SELECT *, ROW_NUMBER() OVER (PARTITION BY [partNumber] 
ORDER BY [date] DESC) AS i FROM [myDB].[dbo].[PartOrders] 
WHERE [partDescription] like '%motor%' )

SELECT * FROM cte WHERE i = 1

我有Microsoft ActiveX Data Objects 6.1库的参考

我使用的VBA代码是:

Dim conn as ADODB.Connection
Dim sql as String
Dim rst as ADODB.Recordset

Set conn = New ADODB.Connection
conn.ConnectionString = myConnectionString
conn.Open

sql = ";WITH cte AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY " & _
      "[partNumber] ORDER BY [date] DESC) AS i " & _
      "FROM [myDB].[dbo].[PartOrders]" & _
      "WHERE [partDescription] like '%motor%' ) " & _
      "SELECT * FROM cte WHERE i = 1 "

Set rst = New ADODB.Recordset
rst.Open sql, conn, adOpenStatic, adLockReadOnly, adCmdText

debug.print rst.recordcount

conn.Close
Set rst = Nothing
Set conn = Nothing

我的代码在立即窗口中打印“-1”

我添加了前面的“;”根据另一个问题回复的推荐我的查询。它没有什么区别。

我已验证以下查询字符串返回记录集:

sql = "SELECT *, ROW_NUMBER() OVER (PARTITION BY " & _
      "[partNumber] ORDER BY [date] DESC) AS i " & _
      "FROM [myDB].[dbo].[partNumbers]" & _
      "WHERE [partDescription] like '%motor%'"

我正在使用CTE,因为需要收集表的整个记录​​,但只有不同的部分描述。我不想看到电机订购了20次。我希望看到电机至少与其他相关领域一起订购了一次。我正在搜索一张包含730,000条记录的表格,其中有10,000台电机的记录,但只有500种不同的类型。

我愿意使用不同的查询,如果它会得到相同的结果,但我真的好奇为什么我当前的查询不会产生任何记录。我希望这不是由于ADODB和VBA不兼容。

感谢您从其他人那里得到的所有帮助,我感谢您提供给我的任何帮助。

2 个答案:

答案 0 :(得分:1)

Parfait 在我对原始问题的评论中为我提供了一个解决方案。将我的连接字符串提供程序更改为驱动程序不起作用。它导致Run-time error '-2147467259 (80004005)'

我在查询中使用了派生表,而不是CTE。

在VBA中为我返回记录计数的SQL查询是:

SELECT main.*
FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY [partNumber] 
ORDER BY [date] DESC) AS i FROM [myDB].[dbo].[PartOrders] 
WHERE [partDescription] like '%motor%') 
AS main WHERE main.i = 1

谢谢!

答案 1 :(得分:0)

除了我按照user7638417的建议使用Driver之外,我遇到了同样的问题。当记录集返回时,记录计数为-1,但是,当我将行插入电子表格时,它们全部都存在(24)。在示例中使用简化查询,实际查询更为复杂,这导致我采用了CTE方法。

    Dim sql As String
    Dim dbConn As New ADODB.Connection
    Dim dbRS As New ADODB.Recordset
    Dim rows As Integer

    sql = "WITH S1 AS ( SELECT Lot, CollectDt, Mark, Slot, Thick1, Thick2 From Table1 )"
    sql = sql + " WHERE Lot = 'lotnumber' "
    sql = sql + " SELECT * FROM S1 WHERE Thick2 <> "UNKNOWN" ORDER BY Slot "

    dbConn.ConnectionString = "Driver={SQL Server};server=myserver;database=production;uid=guest;pwd=guest"
    dbConn.Open
    dbConn.CommandTimeout = 600
    dbRS.Open sql, dbConn, adOpenStatic, adLockReadOnly
        
    Dim totRow As Integer
    totRow = dbRS.RecordCount + 2

   ' If (dbRS.RecordCount > 0) Then
        Sheet1.Cells(2, 1).CopyFromRecordset dbRS
   ' End If

我不得不注释掉对数据的检查,以便从记录集中获取数据。 totRow中的值返回为1而不是26,该值是导致其他情况稍后在代码中失败的期望值。 SQL Server版本:13.0.4001.0 Excel版本:2016