2012-04-27 21 views
17

ho scritto Excel VBA:
VBA, ADO.Connection e query parametri

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

script funzionano bene, ma voglio aggiungere parametri ad esso. Ad esempio "where (parentid = myparam)", dove myparam impostato all'esterno della stringa di query. Come posso farlo?

Naturalmente posso modificare la stringa di query, ma penso che non sia molto saggio.

risposta

25

È necessario utilizzare un oggetto ADODB.Command a cui è possibile aggiungere parametri. Ecco come appare

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 

Il punto di domanda nel CommandText è il segnaposto per il parametro. Credo, ma non sono sicuro, che l'ordine in cui apponi i parametri deve corrispondere all'ordine dei punti interrogativi (quando ne hai più di uno). Non lasciatevi ingannare dal fatto che il parametro sia denominato "parentid" perché non penso che ADO si preoccupi del nome diverso dall'identificazione.

+1

Grazie, codice funziona bene :) – Alexey

+2

Credo che tu sia corretto sull'ordine dei parametri. Questo mi ha fatto inciampare quando venivo da C# .Net e poi codificato VBScript. – Coops

+0

Oppure potresti semplicemente ... .CommandText = "SELECT * FROM table WHERE parentid =" & myparam & "; " –

1

esempio alternativo restituzione di un comando da una funzione:

  1. Quando si utilizza adVarChar tipo di dati, l'argomento size a cmd.CreateParameter (ad esempio 255) è necessaria:

    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 
    

    Un paio di cose da notare . Non fornendo risulta un errore di run-time 3708: Application-defined o object-defined, come indicato nella documentation:

    Se si specifica un tipo di dati di lunghezza variabile nel tipo di argomento, è necessario eseguire passaggio un argomento Size o impostare la proprietà Size dell'oggetto Parameter prima di aggiungerlo alla raccolta Parameters; altrimenti, si verifica un errore.

  2. Se la proprietà cmd.ActiveConnection viene impostata quando cmd.CommandText è impostato, e cmd.CommandText contiene parametri denominati, cmd.Parameters verrà popolato di conseguenza. Chiamare in seguito cmd.Parameters.Append potrebbe causare duplicati. Per esempio:

    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 
    

    Credo che questo sia ciò che si intende nel documentation, che è leggermente imprecisa:

    Se la proprietà Preparato dell'oggetto Command è impostata su true e l'oggetto Command è legato a una connessione aperta quando si imposta la proprietà CommandText, ADO prepara la query (ovvero, un modulo compilato della query memorizzata dal provider) quando si richiamano i metodi Execute o Open.

    Per ovviare al problema, impostare cmd.CommandText o cmd.ActiveConnection dopo aver aggiunto i parametri.

Problemi correlati