使用单元格值范围内的条件运行 SQL 查询列表
Posted
技术标签:
【中文标题】使用单元格值范围内的条件运行 SQL 查询列表【英文标题】:Run list of SQL queries using conditions from range of cell values 【发布时间】:2019-01-26 13:21:58 【问题描述】:我正在尝试运行 SQL 查询列表,其中存在“代码”条件并且值位于另一个工作表上的一系列单元格中(从单元格 A2 到 A385)。
我有下面的代码,但是,我得到一个无效的 SQLQueries 对象名称!$A2:A385
所以,我知道语法不正确,但无论阅读大量文章,我都在努力找到正确的语法。
Sub RunSQLQueries()
'Select SQLQueries sheet
Sheets("SQLQueries").Activate
'Initializes variables
Dim cnn As New ADODB.Connection
Dim rst As New ADODB.Recordset
Dim ConnectionString As String
Dim StrQuery As String
'Setup the connection string for accessing MS SQL database
ConnectionString = "Provider=SQLOLEDB; Data Source=HOSTNAME; Initial Catalog=DBNAME; UID=domain\user; Integrated Security=SSPI"
'Opens connection to the database
cnn.Open ConnectionString
'Timeout
cnn.CommandTimeout = 900
'Build SQK queries
StrQuery = "SELECT * FROM table WHERE code IN (SELECT * FROM [SQLQueries!$A2:A385])"
'Performs the queries
rst.Open StrQuery, cnn
'Select Results sheet
Sheets("Results").Activate
'Dumps all the results from the StrQuery into cell A2 of the active sheet
Range("A2").CopyFromRecordset rst
End Sub
我期望的结果是使用值范围中的每个条件运行 SQL 查询,结果从单元格 A2 向下填充到“结果”表中
【问题讨论】:
【参考方案1】:查询字符串按字面意思发送到数据库服务器,并且由于您的 sql 尝试引用服务器无法访问的 excel 列表,因此会返回错误。服务器正在查找名为 [SQLQueries!$A2:A385] 的表
要坚持您当前的计划,您需要按字面意思传递 IN () 子句或通过格式如下的 vba 变量传递: IN ('item1', 'item2' ...)
注意:如果项目是数字,您可以删除单引号
我建议通过以下方式重新考虑计划 1)如果可以在数据库端进行调整:您可以创建一个新的引用表来连接到实际表或创建一个只返回所需行的视图吗?然后,您需要在运行查询之前调整过滤视图/表的工作。这个想法是你不需要每次都调整查询 bc 一个常量 sql 字符串会返回你需要的行 或者 2)如果源表有 100k 行或更少,并且数据不是太宽,只需在新工作表中将所有行选择到 excel 中,然后过滤该工作表(在 excel 中添加一个新列,使用 vlookup 对您的参考表)或在参考表上使用 vlookup 来拉出所需的列
【讨论】:
【参考方案2】:这里有一个建议:
StrQuery = "SELECT * FROM table WHERE code IN (" & _
InList(Sheets("SQLQueries").Range("A2:A385"),True) & ")"
在给定范围内创建 SQL“in”列表的函数:
Function InList(rng As Range, quoted As Boolean)
Dim qt, a, r As Long, c As Long, rv As String, v, sep As String
a = rng.Value
qt = IIf(quoted, "'", "")
For r = 1 To UBound(a, 1)
For c = 1 To UBound(a, 2)
v = Trim(a(r, c))
If Len(v) > 0 Then
rv = rv & sep & qt & v & qt
sep = ","
End If
Next c
Next r
InList = rv
End Function
注意事项:
如果您有数值,则将False
作为第二个参数传递
我不会将它用于非常大的列表
请确保您不会面临可能的 SQL 注入问题:参数化查询始终是可取的,但不适用于“in”列表
【讨论】:
以上是关于使用单元格值范围内的条件运行 SQL 查询列表的主要内容,如果未能解决你的问题,请参考以下文章