【发布时间】:2016-03-30 20:21:15
【问题描述】:
问题描述:在字母数字字符串上使用 Excel 和 ADO (ACE OLEDB 12.0) 连接 2 个表时,ADO 不区分键“a12a”和“A12a”(它将它们视为相同,即不区分大小写)。但是,我的数据中有字母数字键。 Join 会错误链接数据!
我在 Excel 工作簿中构建了一个小示例来重现该行为。 Excel 工作簿包含 3 张工作表:
- AlphaNum1
- AlphaNum2
- 结果
AlphaNum1 Sheet 包含以下数据
Key Val
a12b 1
A12b 2
a12B 3
A12B 4
e12f 7
E12F 8
1234 9
AlphaNum2 Sheet 包含以下数据:
Key Val
a12b 1
A12b 2
a12B 3
A12B 4
c12d 5
C12D 6
1234 9
我使用以下 VBA 代码连接到 ADO 并加入表(LEFT JOIN):
Sub AlphaNumTest()
Dim oAdoConnection As New ADODB.Connection
Dim oAdoRecordset As New ADODB.Recordset
Dim sAdoConnectString As String, sPfad As String
Dim sQuery As String
On Error GoTo ExceptionHandling
sPfad = ThisWorkbook.FullName
sAdoConnectString = "Provider=Microsoft.ACE.OLEDB.12.0; Extended Properties='Excel 12.0 Xml;HDR=YES;';Data Source=" & sPfad
oAdoConnection.Open sAdoConnectString
sQuery = "Select a1.[Key], a2.[Val] from [AlphaNum1$] a1 LEFT JOIN [AlphaNum2$] a2 ON a1.[Key] = a2.[Key]"
With oAdoRecordset
.Source = sQuery
.ActiveConnection = oAdoConnection
.Open
End With
Dim writeRange As Range
Dim headerRange As Range
'Set headerRange = ThisWorkbook.Sheets("WriteHere").Range("A1")
Set writeRange = ThisWorkbook.Sheets("Result").Range("A2")
' print the table header from recordset
For i = 0 To oAdoRecordset.Fields.Count - 1
' careful! the recordset is zero-indexed like it should be! Excel table however starts at index one, thus the i+1~
ThisWorkbook.Sheets("Result").Cells(1, i + 1).Value = oAdoRecordset.Fields(i).Name
' set bold
ThisWorkbook.Sheets("Result").Cells(1, i + 1).Font.Bold = True
Next i
' print the data directly from recordset!
writeRange.CopyFromRecordset oAdoRecordset
CleanUp:
On Error Resume Next ' Lazy skip
oAdoRecordset.Close
oAdoConnection.Close
Set oAdoRecordset = Nothing
Set oAdoConnection = Nothing
Exit Sub
ExceptionHandling:
MsgBox "Fehler: " & Err.Description
Resume CleanUp
End Sub
请注意,我使用 INNER 还是 LEFT JOIN 并不重要;结果是错误的方式 - 在此示例中,我使用 LEFT JOIN 来演示行为。
Result 输出是 AlphaNum1.Key 和 AlphaNum2.Val 通过 LEFT JOIN 连接。
预期结果(我加入时使用“=”而不是 LIKE...)是:
Key Val
a12b 1
A12b 2
a12B 3
A12B 4
e12f
E12F
1234 9
但是 ADO 给了我实际结果(它不区分 Keys 大小写...):
Key Val
a12b 4
a12b 3
a12b 2
a12b 1
A12b 4
A12b 3
A12b 2
A12b 1
a12B 4
a12B 3
a12B 2
a12B 1
A12B 4
A12B 3
A12B 2
A12B 1
e12f
E12F
1234 9
知道为什么 ADO 会这样吗?任何想法如何/如果我可以改变行为?
【问题讨论】:
-
这已经被问及回答here
-
感谢您的回复 - 但是如何使用 ADO 解决问题?当我添加排序规则(使用 COLLATE latin1_bin)打开 RecordSet 时出现错误。使用 BINARY 我得到一个语法错误。 ADO 中有不同的关键字吗?
-
嗯,我的错,我没有仔细阅读你的问题。问题不在于 ADO(ADO 只是中间人),而在于数据库引擎。据我所知,Excel 中的 ACE OLEDB 不支持 COLLATE。您似乎找到了自己的解决方案:)
-
该解决方案有效,但它确实降低了性能......好吧,我猜是情不自禁;)