【发布时间】:2016-04-17 08:25:16
【问题描述】:
VBA ADO 中的以下 SQL 给出了“From 子句中的语法错误”错误。
Sub RunSQL2()
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim strFile As String
Dim strCon As String
Dim strSQL As String
Dim ws As Worksheet
Dim strRangeAddress As String
Dim dataRange As Range
strFile = ThisWorkbook.Path & "\" & ThisWorkbook.Name
strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFile _
& ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open strCon
Set ws = ThisWorkbook.Sheets("mydata")
strRangeAddress = ActiveSheet.Name & "$" & ws.Range("A1:C30020").Address(False, False)
strSQL = strSQL & " (select s.* from "
strSQL = strSQL & " (select t.*, row_number() over (partition by child_level order by child_index,child_level) [rownum] from [" & strRangeAddress & "] t) s "
strSQL = strSQL & " where [rownum] = 1) u "
strSQL = strSQL & " join (select t2.*, 1 as [rownum] from [" & strRangeAddress & "] t2) v "
strSQL = strSQL & " on (v.parent_level = u.child_level and v.[rownum] = u.[rownum]) "
strSQL = strSQL & " union select w.child_index,w.child_level,w.child_level,w.child_index "
strSQL = strSQL & " from [" & strRangeAddress & "] w "
strSQL = strSQL & " where w.child_index = 1 "
strSQL = strSQL & " order by v.child_index;"
rs.Open strSQL, cn
Debug.Print rs.GetString
End Sub
strSQL的debug.print是:
select v.child_index,v.child_level,v.parent_level,u.child_index as parent_index
from
(select s.*
from
(select t.*, row_number() over (partition by child_level order by child_index,child_level) [rownum]
from [mydata$A1:C30020] t
) s
where [rownum] = 1
) u
join
(select t2.*, 1 as [rownum]
from [mydata$A1:C30020] t2
) v on (v.parent_level = u.child_level and v.[rownum] = u.[rownum])
union
select w.child_index,w.child_level,w.child_level,w.child_index
from [mydata$A1:C30020] w
where w.child_index = 1
order by v.child_index;
当我使用简单的 strSQL 字符串时,连接工作并返回结果。这有效:
strSQL = "SELECT * FROM [" & strRangeAddress & "]"
我认为我的语法正确。错误是否可能是由不兼容的 SQL 引起的?比如ADO可以做'Partition by'吗?
我正在使用 Excel 2010 64 位 Office。
【问题讨论】:
-
我已经重新格式化了您的长内联 SQL 查询,因为它根本无法理解。当评论被接受时,再次检查查询以确保这是正确的。稍后我会仔细研究您的问题
-
专业提示:当您使用
strSQL = strSQL &在代码中构建如此长而复杂的查询时,请在每行末尾添加& vbcrlf以便查询变得易于理解当你debug.print strSQL -
您用于连接 Excel 工作簿的 Jet/ACE SQL 引擎在其方言中不支持窗口函数,因此您不能使用
RowNumber()、Over()或Partition。 -
除了@Parfait 提到的问题之外,查询永远不会工作,因为
UNION要求您在第一部分和第二部分中具有相同数量的列。您的查询选择了UNION之前的 5 列和UNION之后的 4 列。 -
感谢 Thomas 看起来很棒。我确实使用换行符,但在这个阶段我喜欢尽量减少复杂性。