我们在VB6 COM库中使用此实用程序方法来执行参数化SQL:
Public Sub ExecSQL(ByVal strSQL As String, ParamArray varParams() As Variant)
'snip - ADODB data access
End Sub
其中varParams是SQL参数信息的二维数组。示例用法是:
ExecSQL("SELECT * FROM People WHERE Name = ?", Array("@p1", adVarChar, 10, "Smith"))
这是久经考验的代码,在正常使用情况下运行良好。我现在处于一种不寻常的情况,其中SQL字符串是可配置的值并且可以包含任意数量的参数,因此我需要做的是将未知数量的参数传递给ParamArray。到目前为止(简化)我的尝试是:
Function ExecConfigurableSql(sqlString As String, parameterValues() As String)
Dim parameters() As Variant
ReDim parameters(UBound(parameterValues)) As Variant
For i = 0 To UBound(parameterValues)
parameters(i) = Array("@p" + CStr(i), adVarChar, 1000, parameterValues(i))
Next
ExecSQL(sqlString, parameters) 'Type Mismatch
End Function
执行SQL的尝试会引发Type Mismatch错误。有没有办法将数组传递给需要ParamArray的函数?或者我在某个地方犯了一个完全独立的错误?
这是动态构建的数组的参数:
这是他们使用逗号分隔的ParamArray语法传递时的样子(可行):
结构看起来和我一样。
答案 0 :(得分:1)
首先,你从来没有在 ExecSQL()中首先需要 ParamArray ,因为你总是在一个参数上传递除了 strSQL 之外的堆栈,即变种数组,
Array("@p1", adVarChar, 10, "Smith")
在第二个清单中。 ParamArray 用于在堆栈中传递未定义的数字或 ,即能够进行如下调用:
ExecSQL "SELECT * FROM People WHERE Name = ?", "@p1", adVarChar
ExecSQL "SELECT * FROM People WHERE Name = ?", "@p1", adVarChar, 10, "Smith"
ExecSQL "SELECT * FROM People WHERE Name = ?", "@p1"
ParamArray 只需获取堆栈上传递的所有参数,并将它们放入数组中。
所以,你可以定义 ExecSQL(),如下所示提供你的代码适应一个较少的Array()层 varParams :
Public Sub ExecSQL(ByVal strSQL As String, varParams() As Variant)
' snip - ADODB data access '
End Sub
话虽如此:
目前, ExecConfigurableSql()中的代码将字符串数组(我假设字段名称)转换为 ExecSQL(),所需的格式,除了(外部)数组可以(并且将)包含排序数组的多个元素(" @ p1",adVarChar,10,"史密斯"。)
ExecSQL()可以处理吗? => 问题#1
[顺便说一句,所有的字段都是1000-char long ??]
问题#2 :参数在 ExecConfigurableSql()中查看时很好,但是一旦你将if传递给 execSQL(), ParamArray 将它包装在另一个数组中,所以你真的最终得到(曾经在 ExecSQL()中),如下所示: / p>
现在,您必须将(未知数量)参数放入数组中,因为您无法将它们传递到堆栈 ParamArray 因为您事先并不知道它们的数量。因此,您无法从那里删除额外的 Array()包装。
您可以摆脱 ExecSQL()中的 ParamArray ,但会破坏您现有的< em> ExecSQL()调用( varParams 只能在 Array()中包装一次而不是两次)。
了解这一切,您有两种选择:
(1)按原样保持声明,让 ExecConfigurableSql()在中进行多个 ExecSQL()调用对于循环(顺便说一下,你将它声明为 Sub ,所以我认为它不会返回任何值); e.g。
Function ExecConfigurableSql(sqlString As String, parameterValues() As String)
For i = 0 To UBound(parameterValues)
Call ExecSQL(sqlString, Array("@p" + CStr(i), adVarChar, 1000, parameterValues(i))
Next
End Function
或
(2)反过来说,改善逻辑&amp;稠度
Function ExecConfigurableSql(sqlString As String, varParamsArray() As Variant)
Dim varParams() As Variant
For i = 0 To UBound(varParamsArray)
varParams = varParamsArray(i)
' snip - ADODB data access '
Next i
End Function
从 ExecSQL()中获取代码并将其放入 ExecConfigurableSql()中指示 - 重要:您必须更新您的代码以解释参数包含少量Array()的事实。
对于 ExecSQL(),删除 ParamArray 关键字并将该方法视为 ExecConfigurableSql()的特殊情况提供一名成员,即:
Function ExecSQL(sqlString As String, varParams() As Variant)
Call ExecConfigurableSql(sqlString, Array(varParams))
End Function