2012-04-27 3 views
17

У меня есть Excel VBA скрипт:
VBA, ADO.Connection и параметры запроса

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

скрипт работает отлично, но я хочу, чтобы добавить параметр к нему. Например: «где (parentid = myparam)», где myparam настроил внешнюю строку запроса. Как мне это сделать?

Конечно, я могу изменить строку запроса, но я думаю, что это не очень мудро.

ответ

25

Вам нужно использовать объект ADODB.Command, к которому вы можете добавить параметры. Вот в основном то, что выглядит как

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 

Вопросительный знак в CommandText является заполнителем для параметра. Я считаю, но я не уверен, что порядок, который вы добавляете, должен соответствовать порядку вопросительных знаков (когда у вас более одного). Не обманывайте себя, что параметр называется «parentid», потому что я не думаю, что ADO заботится об имени, отличном от идентификации.

+1

Спасибо, вы код workfs fine :) – Alexey

+2

Я считаю, что вы правы по порядку параметров. Это сработало, когда я пришел из C# .Net, а затем закодировал VBScript. – Coops

+0

Или вы могли бы просто .. .CommandText = "SELECT * FROM table WHERE parentid =" & myparam & "; " –

1

Альтернативный пример возвращения команды из функции:

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 

Пару вещей отметить:

  1. При использовании adVarChar тип данных, размер аргумента cmd.CreateParameter (например, 255), требуется , Не поставляя это приводит к ошибке во время выполнения 3708: приложения или объект определенные ошибки, как это указано в documentation:

    Если указать тип данных переменной длины в тип аргумента, вы должны либо передать аргумент «Размер» или задайте свойство «Размер» объекта «Параметр» перед добавлением его в коллекцию «Параметры»; в противном случае возникает ошибка.

  2. Если свойство cmd.ActiveConnection устанавливается, когда cmd.CommandText установлен, и cmd.CommandText содержит именованные параметры, cmd.Parameters будут заполнены соответствующим образом. Вызов cmd.Parameters.Append впоследствии может привести к дублированию. Например:

    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 
    

    Я считаю, что это то, что подразумевается в documentation, который немного неточно:

    Если Подготовленные свойство объекта Command установлено значение Да и объект Command является оценка к открытому соединению, когда вы устанавливаете свойство CommandText, ADO подготавливает запрос (то есть скомпилированную форму запроса, который хранится поставщиком) при вызове методов Execute или Open.

    В качестве обходного пути либо установить cmd.CommandText, либо cmd.ActiveConnection после добавления параметров.

Смежные вопросы