Асинхронное выполнение хранимых процедур в MS SQL Server средствами Access 2003

Если у Вас встала задача асинхронно выполнять хранимые процедуры в Microsoft SQL Server, при этом эти процедуры будут запускаться из клиента Access 2003, то данный материал будет Вам полезен, так как в нем я покажу на примере как можно решить данную задачу средствами VBA Access.

Асинхронное выполнение хранимых процедур в MS SQL Server

Для начала давайте разберемся, что мы понимаем под «асинхронное выполнение хранимых процедур». Это то, когда мы запускаем на выполнение хранимую процедуру и, не дожидаясь окончания ее работы, запускаем другую процедуру или вовсе продолжаем работать в клиенте.

Нам это может потребоваться, например, в случаях, когда у нас несколько баз данных и нам одновременно на всех БД нужно из клиента запустить некие процедуры (для чего это может потребоваться неважно). Или, например, процедура очень долго выполняется, а нам необходимо работать в программе дальше.

Итак, а сейчас давайте разберемся, какие средства при этом мы будем использовать. В качестве 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

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

Сохраняем и нажимаем на кнопку, т.е. проверяем работу.

Скриншот 1

Видим, что процедуры выполнились одновременно, асинхронный режим работает.

На этом у меня все, пока!

Понравилась статья? Поделиться с друзьями:
Заметки IT специалиста
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:
Нажимая на кнопку «Отправить комментарий», я даю согласие на обработку персональных данных и принимаю политику конфиденциальности.