Объект ADODB.Command, запуск хранимых процедур в VBA, объект Parameter и коллекция Parameters, метод Execute(), возврат значений в Recordset
В самых простых вариантах, когда можно получить и изменять данные напрямую в таблицах, можно обойтись объектом Recordset. Однако во многих ситуациях возможностей только этого объекта недостаточно. Как уже говорилось, предпочтительнее производить любое внесение изменений на источник данных при помощи хранимых процедур. Часто существует потребность в создании временных таблиц и других объектов на сервере. Бизнес-логика многих приложений (начисление процентов, абонентской платы, формирование специальных отчетов с вычислениями и т.п.) также реализована в виде хранимых процедур, поэтому в реальных приложениях одним объектом Recordset не обойтись.
Для выполнения команд SQL на сервере (в том числе запуска хранимых процедур, команд DDL для создания объектов, выполнения служебных операций типа резервного копирования, восстановления, изменения параметров работы) необходимо использовать объект Command.
Создание этого объекта производится очень просто:
Dim cmd As ADODB.Command
Set cmd = CreateObject("ADODB.Command")
Следующее, что нужно сделать — назначить объекту Command объект подключения Connection. Для этой цели предназначено свойство Command.ActiveConnection. Ему можно передать готовый объект Connection, а можно сформировать этот объект неявно, используя в качестве значения свойства ActiveConnection строку подключения. Рекомендуется всегда предавать готовый объект подключения: во-первых, так для соединения можно настроить больше параметров, а во-вторых, если вы используете в приложении несколько объектов Command, можно использовать для каждого такого объекта одно-единственное подключение, что экономит ресурсы. В нашем примере мы используем созданный нами ранее объект Connection:
cmd.ActiveConnection = cn
Следующая наша задача — выбрать тип команды. В принципе, для многих источников можно его и не выбирать — модули ADO постараются сами выяснить у источника данных, что это за команда (хранимая процедура, SQL-запрос и т.п.), однако лучше всегда его определять: экономится время и системные ресурсы, уменьшается вероятность ошибок. Для выбора типа команды используется свойство CommandType. Значения, которые ему можно присвоить, аналогичны возможным значениям параметра Options метода Open() объекта Recordset, которое было рассмотрено выше. Например, если мы передаем команду на выполнение хранимой процедуры, то присвоить соответствующее значение можно так:
cmd.CommandType = adCmdStoredProc
Следующее действие — определить текст команды, которая будет выполняться. Делается это при помощи свойства CommandText. Например, если мы хотим запустить на выполнение хранимую процедуру CustOrderHist, то соответствующий код может выглядеть так:
cmd.CommandText = "CustOrderHist"
Чаще всего хранимая процедура требует передачи ей одного или нескольких параметров. Делается это при помощи коллекции Parameters и объектов Parameter. Для определения параметров можно использовать два способа:
cmd.Parameters.Refresh
cmd.Parameters(1) = "ALFKI"
Dim Prm As ADODB.Parameter
Set Prm = cmd.CreateParameter("CustomerID", adVarWChar, adParamInput, 5, "ALFKI")
cmd.Parameters.Append Prm
После этого команду необходимо запустить на выполнение. Для этого используется метод Execute(). Самый простой способ его вызова выглядит так:
cmd.Execute
Этот метод принимает также три необязательных параметра, при помощи которых можно дополнительно определить параметры, тип вызываемой команды и т.п.
Некоторые хранимые процедуры и передаваемые команды не требуют возврата каких-либо значений (кроме кода ошибки), но так бывает редко. Как же принять значения, возвращаемые выполняемой командой?
Если возвращаемое значение официально зарегистрировано как возвращаемый параметр (например, оно помечено ключевым словом OUT в определении хранимой процедуры), то это значение будет присвоено соответствующему параметру объекта Command, и до него можно будет добраться обычным способом — при помощи свойства Value.
Если же, как в нашем примере с CustOrderHist, возвращаемое значение просто сбрасывается в поток вывода (в нашем случае возвращается набор записей), то можно использовать два способа:
Dim rs2 As ADODB.Recordset
Set rs2 = cmd.Execute()
Debug.Print rs2.GetString
Dim rs2 As ADODB.Recordset
Set rs2 = CreateObject("ADODB.Recordset")
rs2.Open cmd
Debug.Print rs2.GetString
Некоторые другие свойства и методы объекта Command: