简体   繁体   English

VBA,ADO.Connection和查询参数

[英]VBA, ADO.Connection and query parameters

I have excel VBA script: 我有excel VBA脚本:

Set cоnn = CreateObject("ADODB.Connection")
conn.Open "report"
Set rs = conn.Execute("select * from table" ) 

Script work fine, but i want to add parameter to it. 脚本工作正常,但我想添加参数。 For example " where (parentid = myparam )", where myparam setted outside query string. 例如“where(parentid = myparam )”,其中myparam在查询字符串外设置。 How can i do it? 我该怎么做?

Of course i can modify query string, but i think it not very wise. 当然我可以修改查询字符串,但我认为这不是很明智。

You need to use an ADODB.Command object that you can add parameters to. 您需要使用可以添加参数的ADODB.Command对象。 Here's basically what that looks like 这基本上就是这样的

Sub adotest()

    Dim Cn As ADODB.Connection
    Dim Cm As ADODB.Command
    Dim Pm As ADODB.Parameter
    Dim Rs as ADODB.Recordset

    Set Cn = New ADODB.Connection
    Cn.Open "mystring"
    Set Cm = New ADODB.Command
    With Cm
        .ActiveConnection = Cn
        .CommandText = "SELECT * FROM table WHERE parentid=?;"
        .CommandType = adCmdText

        Set Pm = .CreateParameter("parentid", adNumeric, adParamInput)
        Pm.Value = 1

        .Parameters.Append Pm

        Set Rs = .Execute
    End With

End Sub

The question mark in the CommandText is the placeholder for the parameter. CommandText中的问号是参数的占位符。 I believe, but I'm not positive, that the order you Append parameters must match the order of the questions marks (when you have more than one). 我相信,但我不是肯定的,你追加参数的顺序必须与问号的顺序相匹配(当你有多个时)。 Don't be fooled that the parameter is named "parentid" because I don't think ADO cares about the name other than for identification. 不要被愚弄,参数被命名为“parentid”,因为我不认为ADO关心除了识别之外的名称。

Alternative example returning a command from a function: 从函数返回命令的替代示例:

Function BuildCommand(conn As ADODB.Connection) As ADODB.Command
    Dim cmd As ADODB.Command
    Set cmd = New ADODB.Command
    cmd.ActiveConnection = conn
    cmd.CommandType = adCmdText
    cmd.Parameters.Append cmd.CreateParameter("@name", adVarChar, adParamInput, 255, "Dave")
    cmd.CommandText = "SELECT * FROM users WHERE name = @name;"
    Set BuildCommand = cmd
End Function

A couple things to note: 有几点需要注意:

  1. When using adVarChar data type, the size argument to cmd.CreateParameter (eg 255) is required. 使用adVarChar数据类型时,需要cmd.CreateParameter (例如255)的size参数。 Not supplying it results a run-time error 3708: Application-defined or object-defined error, as indicated in the documentation : 不提供它会导致运行时错误3708:应用程序定义的错误或对象定义的错误,如文档中所示

    If you specify a variable-length data type in the Type argument, you must either pass a Size argument or set the Size property of the Parameter object before appending it to the Parameters collection; 如果在Type参数中指定可变长度数据类型,则必须先传递Size参数或设置Parameter对象的Size属性,然后再将其附加到Parameters集合; otherwise, an error occurs. 否则,会发生错误。

  2. If the cmd.ActiveConnection property is set when cmd.CommandText is set, and cmd.CommandText contains named parameters, cmd.Parameters will be populated accordingly. 如果在设置cmd.CommandText时设置了cmd.ActiveConnection属性,并且cmd.CommandText包含命名参数,则将相应地填充cmd.Parameters Calling cmd.Parameters.Append afterwards could result in duplicates. 之后调用cmd.Parameters.Append可能会导致重复。 For example: 例如:

     cmd.ActiveConnection = conn cmd.CommandType = adCmdText Debug.Print cmd.Parameters.Count ' 0 cmd.CommandText = "SELECT * FROM users WHERE name = @name;" Debug.Print cmd.Parameters.Count ' 1 cmd.Parameters.Append cmd.CreateParameter("@name", adVarChar, adParamInput, 255, "Dave") Debug.Print cmd.Parameters.Count ' 2 

    I believe this is what is meant in the documentation , which is slightly inaccurate: 我相信这就是文档中的含义,这有点不准确:

    If the Prepared property of the Command object is set to True and the Command object is bound to an open connection when you set the CommandText property, ADO prepares the query (that is, a compiled form of the query that is stored by the provider) when you call the Execute or Open methods. 如果在设置CommandText属性时将Command对象的Prepared属性设置为True并且Command对象绑定到打开的连接,则ADO准备查询(即,由提供程序存储的查询的已编译形式)当您调用Execute或Open方法时。

    As a workaround, either set cmd.CommandText or cmd.ActiveConnection after adding parameters. 作为解决方法, cmd.ActiveConnection在添加参数后设置cmd.CommandTextcmd.ActiveConnection

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM