这是我关于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不兼容。
感谢您从其他人那里得到的所有帮助,我感谢您提供给我的任何帮助。
答案 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