VB6 - 传递一个数组作为函数的ParamArray参数

时间:2014-06-19 15:26:50

标签: sql arrays vb6 ado

我们在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的函数?或者我在某个地方犯了一个完全独立的错误?

这是动态构建的数组的参数:

Dynamic array 这是他们使用逗号分隔的ParamArray语法传递时的样子(可行):

ParamArray

结构看起来和我一样。

1 个答案:

答案 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>

enter image description here

现在,您必须将(未知数量)参数放入数组中,因为您无法将它们传递到堆栈 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;稠度

  • 既然您仍然可以使用声明&amp;实现 ExecConfigurableSql(),更改第二个参数以期望一个数组数组(&#34; @ p1&#34;,adVarChar,10,&#34; Smith&#34;) - 就像成员一样(而不仅仅是字段名称)。

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