能通过考试吗 NULL
价值 QueryTable.Parameters
用于(我的)sql查询?
从另一个答案,我们可以看出,这是可能的 ADODB.Command
,但不幸的是, ADODB
在excel for mac中不可用,我正在开发的应用程序应该可以同时在windows和mac上运行。
下面的内容被确认为windows的错误(我假设是mac)。
如果设置 param_value
但一旦你尝试使用null,它就会失败得很厉害。
Option Explicit
Sub Test()
' SQL '
Dim sql As String
sql = "SELECT ? AS `something`"
Dim param_value As Variant
'param_value = "hello" ' this works
'param_value = Null ' this does NOT work
' QUERY & TABLE CONFIG '
Dim my_dsn As String
Dim sheet_name As String
Dim sheet_range As Range
Dim table_name As String
my_dsn = "ODBC;DSN=my_dsn;"
sheet_name = "Sheet1"
Set sheet_range = Range("$A$1")
table_name = "test_table"
' EXECUTE QUERY '
Dim qt As QueryTable
Set qt = ActiveWorkbook.Worksheets(sheet_name).ListObjects.Add( _
SourceType:=xlSrcExternal, _
Source:=my_dsn, _
Destination:=sheet_range _
).QueryTable
With qt
.ListObject.Name = table_name
.ListObject.DisplayName = table_name
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = False
.CommandText = sql
End With
Dim param As Parameter
Set param = qt.Parameters.Add( _
"param for something", _
xlParamTypeUnknown _
)
param.SetParam xlConstant, param_value
qt.Refresh BackgroundQuery:=False
End Sub
设置时 param_value
对于“hello”,成功的结果如下所示:
(下面这个命令提示屏幕截图是mysql日志记录的内容)。
这是设置时的错误 param_value
设置为空:
您可以从mysql日志中看到,成功的查询首先执行 Prepare
,然后是 Execute
查询的名称。
而失败的null查询执行 Prepare
,但从未到达终点 Execute
.
在线搜索 run-time error -2147417848 (80010108)
无济于事;从“冻结窗格”问题到“用户窗体”问题,人们都在报告这一点,我看不到任何与此相关的信息 QueryTable
.
vba代码不仅无法按预期工作,还会以某种方式损坏工作簿:
(在查询失败后尝试保存文件时发生这种情况;关闭而不保存,您可以重新打开)。
mysql日志显示vba连接失败 Quit
,并且excel文件被破坏了,这让我觉得在 QueryTable.Parameters
,但这也是底层软件中的一个bug。
我遗漏了什么,还是无法将空参数传递给查询表?
更新
作为对接近投票的回应:我的观点是,应该有一种方法将参数作为 NULL
,正如这里引用的。
更新
由于null的问题,以及xlparamtypedate没有从十进制转换为'yyyy-mm-dd',我最终滚动了自己的参数化类模块。下面已经贴出了这个问题的答案。
1条答案
按热度按时间ryoqjall1#
如果有人知道如何用
QueryTable.Parameters
,然后发帖,我会选择你的答案。但下面是一个定制的解决方案。对所有人
SqlTypes
除外char
,参数化是自定义的,但是char
仍然使用QueryTable.Parameters
因为在尝试实现时可能会出现各种逃逸的情况。编辑到上面的删除线:我实际上已经恢复到用这个自定义参数化手动处理char参数。我忘记了遇到的确切的角落案例,但得出的最终结论是vba参数化对于具有特定查询字符串的特定char param的单一案例是失败的。。。我完全不知道失败点在哪里,因为它是在microsoft的vba方法的黑盒中生成的,但是我确认了一个事实,即字符串param根本没有被传递到(我的)sql引擎,因为它看起来是随机的。我的经验是
QueryTable.Parameters
方法根本不可信。我的建议是取消注解GetValueAsSqlString = Replace$(Replace$(Replace$(CStr(value), "\", "\\"), "'", "\'"), """", "\""")
并移除IF char THEN
内部逻辑SetQueryTableSqlAndParams
. 由于不同的引擎有不同的文字字符,我把这作为一个练习留给读者在他们的环境中处理;例如,上述Replace$()
代码可能具有(也可能不具有)您希望在包含\n
.我注意到querytable的一个不一致之处是,如果执行
SELECT "hello\r\nthere" AS s
,查询将返回一个换行符(如预期),但如果使用querytable.parametersxlParamTypeChar
与"hello\r\nthere"
,则返回原始反斜杠。所以你必须使用vbCrLf
,等等。SqlParams
类模块:依赖模块:
用法示例: