Чтение таблицы, выдаваемой SQL Server Stored Proc во время каждой итерации цикла While

0

Я выполняю хранимую процедуру, и внутри хранимой процедуры есть цикл WHILE. Каждый раз, когда итерация происходит в цикле WHILE, она выводит таблицу (показывающую ее прогресс). Я хотел бы захватить эту таблицу и прочитать ее в.NET (используя драйвер.NET SQLClient). Я хотел бы иметь возможность прочитать эту таблицу прогресса, как создается таблица (например, в SSMS) и NOT, когда хранимая процедура завершена.

PS: Мне все равно, какой язык.NET вам нравится - решение или идеи на любом языке были бы весьма признательны.

Теги:

1 ответ

2
Лучший ответ

Думаю, я придумал способ сделать это. Я начал с создания небольшой локальной базы данных с одной таблицей, которая называется Table1, которая имеет текстовый столбец с именем status. Я также создал StoredProcedure под названием StoredProcedure1. Это выглядит так:

CREATE PROCEDURE dbo.StoredProcedure1
/*
(
@parameter1 int = 5,
@parameter2 datatype OUTPUT
)
*/ AS
declare @setCount int 
declare @result table (cnt int)
set @setCount = 0

insert into Table1 (status) VALUES ('Starting');

while @setCount < 5
begin
    WAITFOR DELAY '00:00:03';

    insert into @result (cnt)
    select @setCount
    set @setCount = @setCount + 1;

    update Table1 set status='Iteration ' + cast(@setCount as varchar);
end

RETURN

Хранимая процедура просто вставляет начальное значение статуса в таблицу1, а затем циклически проходит через 5 итераций, задерживая три секунды для каждой итерации, чтобы имитировать длительный процесс. В конце каждой итерации поле статуса обновляется, чтобы отразить следующую итерацию.

Затем я создал проект WindowsForms с единственной формой, которая имеет одну метку. Я создал частный метод для выполнения хранимой процедуры как долгого процесса.

    Private Sub LongRunningProcess()
    Dim _conn As New SqlClient.SqlConnection("Data Source=.\sqlexpress;Initial Catalog=MARS_ProcTest;Integrated Security=True;MultipleActiveResultSets=True;")
    Dim cmd As New SqlClient.SqlCommand("exec StoredProcedure1", _conn)
    Dim ds As New DataSet

    _conn.Open()
    cmd.ExecuteNonQuery()
    _conn.Close()
End Sub

Затем я создал другой метод, который будет проверять статус в таблице1 до завершения хранимой процедуры.

Private Sub StatusChecker()
    Dim _conn As New SqlClient.SqlConnection("Data Source=.\sqlexpress;Initial Catalog=MARS_ProcTest;Integrated Security=True;MultipleActiveResultSets=True;")
    Dim cmd As New SqlClient.SqlCommand("select status from Table1", _conn)
    Dim ds As New DataSet

    _conn.Open()

    While Not _done
        Dim stat As String

        stat = cmd.ExecuteScalar()

        If Me.InvokeRequired() Then
            Me.Invoke(Sub()
                          Me.Label1.Text = stat
                      End Sub)
        Else
            Me.Label1.Text = stat
        End If
    End While

    _conn.Close()

End Sub

Я добавил простой способ перевернуть private boolean в классе формы в true, когда LongRunningProcess завершен.

Private Sub FinishProcess()
    '_done is a private variable on the form class.
    _done = True
End Sub

Наконец, в форме Load event я использую.NET-библиотеку задач, чтобы запустить проверку состояния и длительный процесс, гарантируя, что задача LongRunningProcess будет продолжена с завершением процесса.

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load

    Task.Factory.StartNew(AddressOf StatusChecker)
    Task.Factory.StartNew(AddressOf LongRunningProcess).ContinueWith(AddressOf FinishProcess)

End Sub

Поэтому, когда все это выполняется, у нас есть фоновые потоки, выполняющие длительную задачу и проверяющие статус так часто, как нужно. Поскольку хранимая процедура обновляет таблицу 1 с информацией и выполняет эти инструкции в разных транзакциях, вы видите обновления по мере их возникновения.

  • 0
    Это довольно круто! Спасибо...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню