Если у Вас встала задача асинхронно выполнять хранимые процедуры в Microsoft SQL Server, при этом эти процедуры будут запускаться из клиента Access 2003, то данный материал будет Вам полезен, так как в нем я покажу на примере как можно решить данную задачу средствами VBA Access.
Для начала давайте разберемся, что мы понимаем под «асинхронное выполнение хранимых процедур». Это то, когда мы запускаем на выполнение хранимую процедуру и, не дожидаясь окончания ее работы, запускаем другую процедуру или вовсе продолжаем работать в клиенте.
Нам это может потребоваться, например, в случаях, когда у нас несколько баз данных и нам одновременно на всех БД нужно из клиента запустить некие процедуры (для чего это может потребоваться неважно). Или, например, процедура очень долго выполняется, а нам необходимо работать в программе дальше.
Итак, а сейчас давайте разберемся, какие средства при этом мы будем использовать. В качестве SQL сервера для примера у меня будет выступать SQL Server 2012, в качестве клиента ADP проект Access 2003. В качестве инструментов реализации асинхронного выполнения процедур я буду использовать объект ADODB.Command, который позволяет это делать, при этом мы можем сделать так, чтобы клиент оповестил нас об окончание работы хранимых процедур.
Исходные данные
Допустим, у нас есть база данных Test, а в ней есть хранимые процедуры SP_Test_1 и SP_Test_2.
USE [Test] GO CREATE PROCEDURE dbo.SP_Test_1(@TestParam AS INT) AS BEGIN /* SQL инструкция Вашей хранимой процедуры Я в качестве примера просто приостанавливаю выполнение процедуры на 5 секунд */ WAITFOR DELAY '00:00:05'; SELECT @TestParam END GO CREATE PROCEDURE dbo.SP_Test_2(@TestParam AS INT) AS BEGIN /* SQL инструкция Вашей хранимой процедуры Я в качестве примера просто приостанавливаю выполнение процедуры на 5 секунд */ WAITFOR DELAY '00:00:05'; SELECT @TestParam END
Заметка! Для комплексного изучения языка T-SQL рекомендую посмотреть мои видеокурсы по T-SQL, в которых используется последовательная методика обучения и рассматриваются все конструкции языка SQL и T-SQL.
Adp проект настроен на работу с базой данных.
Задача. Нам необходимо запустить эти процедуры в асинхронном режиме, чтобы вторая, независимо от того завершила ли выполнение первая процедура, начала свою работу.
Асинхронный запуск хранимых процедур из Access 2003
Как я уже сказал данный способ, подразумевает использование объекта ADODB.Command. Для решения задачи на форму добавим кнопку с названием TestExec, а в обработчик события «Нажатие кнопки» вставляем следующий код (он прокомментирован).
Private Sub TestExec_Click() On Error GoTo Err1 'Переменные Dim SQLCmd1 As ADODB.Command, SQLCmd2 As ADODB.Command Dim TestRS1 As Recordset, TestRS2 As Recordset Dim StartTime As Date, TimeALL As String Dim TmpTimeHour As String, TmpTimeMinute As String, TmpTimeSecond As String 'Создание объектов Set SQLCmd1 = New ADODB.Command Set SQLCmd2 = New ADODB.Command 'Настройки объекта SQLCmd1 With SQLCmd1 .CommandTimeout = 0 .ActiveConnection = CurrentProject.Connection 'Текущее соединение .CommandType = adCmdStoredProc 'Будем выполнять хранимую процедуру .CommandText = "dbo.SP_Test_1" 'Имя хранимой процедуры 'Параметр хранимой процедуры .Parameters.Append .CreateParameter("@TestParam", adBigInt, adParamInput, , 1) End With 'Настройки объекта SQLCmd2 With SQLCmd2 .CommandTimeout = 0 .ActiveConnection = CurrentProject.Connection .CommandType = adCmdStoredProc .CommandText = "dbo.SP_Test_2" .Parameters.Append .CreateParameter("@TestParam", adBigInt, adParamInput, , 2) End With 'Запоминаем время старта 'Просто для того чтобы знать сколько выполнялись наши процедуры StartTime = Now TmpTimeHour = Hour(StartTime) TmpTimeMinute = Minute(StartTime) TmpTimeSecond = Second(StartTime) 'Запускаем процедуры в асинхронном режиме Set TestRS1 = SQLCmd1.Execute(, , adAsyncExecute) 'Set TestRS1 = SQLCmd1.Execute 'Запуск в обычном режиме Set TestRS2 = SQLCmd2.Execute(, , adAsyncExecute) 'Ждем пока процедуры выполнятся Do Until TestRS1.State <> 4 And TestRS2.State <> 4 DoEvents Loop 'Узнаем продолжительность выполнения процедур 'И выводим время в формате "00:00:00" 'Часы If Hour(Now - StartTime) < 10 Then TmpTimeHour = "0" & Hour(Now - StartTime) Else TmpTimeHour = Hour(Now - StartTime) End If 'Минуты If Minute(Now - StartTime) < 10 Then TmpTimeMinute = "0" & Minute(Now - StartTime) Else TmpTimeMinute = Minute(Now - StartTime) End If 'Секунды If Second(Now - StartTime) < 10 Then TmpTimeSecond = "0" & Second(Now - StartTime) Else TmpTimeSecond = Second(Now - StartTime) End If 'Формируем время TimeALL = TmpTimeHour & ":" & TmpTimeMinute & ":" & TmpTimeSecond MsgBox "Операция выполнена за " & TimeALL, vbInformation, "Сообщение" 'Очищаем Recordset Set TestRS1 = Nothing Set TestRS2 = Nothing Ex1: Exit Sub Err1: MsgBox Err.Description End Sub
Сохраняем и нажимаем на кнопку, т.е. проверяем работу.
Видим, что процедуры выполнились одновременно, асинхронный режим работает.
На этом у меня все, пока!