Динамический Sql с задержкой ожидания для проверки состояния

#sql #sql-server

#sql #sql-сервер

Вопрос:

я пытаюсь реализовать логику, в которой приведенный ниже код выполняется каждые 30 секунд до тех пор, пока [execution_result] = ‘Running’ .

Транзакция завершается только тогда, когда [execution_result] <> ‘Выполняется’

Ниже приведен код, но он, к сожалению, не работает.

Спасибо

 BEGIN

;WITH CTES AS
(
SELECT   e.package_name ,
e.execution_id, 
e.[executable_name] , 
es.[execution_path] , 
es.[execution_duration] , 
es.start_time,
es.end_time,
[execution_result] = CASE ex.[status]
               WHEN 1 THEN 'created' 
               WHEN 2 THEN 'Running' 
               WHEN 3 THEN 'canceled' 
               WHEN 4 THEN 'failed' 
               WHEN 5 THEN 'pending' 

END 

FROM    [catalog].[executables] e 
INNER JOIN [catalog].[executable_statistics] es ON es.[executable_id] = e.[executable_id] 
INNER JOIN [catalog] .[executions] ex ON e.execution_id = ex.execution_id


)

DECLARE @execution_result varchar (100) 
set @execution_result = select execution_result from CTES

IF  @execution_result = 'Running'

WAITFOR DELAY '00:00:30'

END
  

Комментарии:

1. Не работает?? Пожалуйста, уточните, что не работает .. например, описание ошибки, которое вы have..as Я вижу, что объявление переменной @execution_result и операторы set неверны.

2. @Deepshikha: получена ошибка: сообщение 156, уровень 15, состояние 1, строка 34 Неправильный синтаксис возле ключевого слова ‘DECLARE’. Сообщение 156, уровень 15, состояние 1, строка 35 Неправильный синтаксис возле ключевого слова ‘select’.

3. Начните сначала. Никто не может научить вас базовому синтаксису на таком форуме, как этот, и у вас много ошибок. Во-первых, нет цикла, поэтому цель «запускать каждые 30 секунд» не может быть достигнута. Поэтому я предлагаю вам начать все сначала и разбить вашу задачу на этапы. Сначала напишите цикл, который выполняется один раз каждые 30 секунд. И подумайте, насколько проблематичен этот подход. Как только ваш цикл заработает, добавьте базовый запрос для получения результатов (но ничего с ним не делайте). Когда это сработает, добавьте то, для чего предназначалось ваше назначение в переменную execution_result . Обратите внимание, что вы не можете назначить строку скалярной переменной.

Ответ №1:

Объявите переменную перед определением общего табличного выражения CTE, как показано ниже, поскольку за CTE должен следовать один оператор SELECT, INSERT, UPDATE или DELETE, который ссылается на некоторые или все столбцы CTE.

 DECLARE @execution_result varchar (100) ;

WITH CTES AS
(
  

И установите значение переменной как:

 select @execution_result =  execution_result from CTES
  

Кроме того, чтобы сохранить выполнение кода до тех пор, пока не будет выполнено условие прерывания, которое находится здесь [execution_result] is <> 'Running' , мы можем инкапсулировать всю логику в While цикл как:

 SET NOCOUNT ON; 
--Declare all variables 
DECLARE @execution_result varchar (100) ;
--Define an infinite loop
WHILE 1=1
    BEGIN

                WITH CTES AS
                (
                 --All the logic goes here
                )
                select @execution_result =  execution_result from CTES
                --check exit condition here

                IF  @execution_result = 'Running'
                Begin
                     WAITFOR DELAY '00:00:30'
                     CONTINUE;
                End
                Else
                Begin
                     BREAK;
                End

    END;
  

Надеюсь, этот псевдокод поможет!!

Ответ №2:

Похоже, вам нужно будет повторно выполнить запрос после 30 секунд ожидания, чтобы повторно проверить статус. Судя по вашему запросу, похоже, что вы проверяете его только один раз, и, возможно, ваша программа завершится через 30 секунд. Возможно, здесь вам нужна do...while логика типа цикла.

Комментарии:

1. на самом деле это верный аргумент. он предлагает вам продолжать проверку, пока вы не получите нужный вам статус.

2. @Deepak: я пытаюсь реализовать логику, которая продолжает проверять, пока статус не будет запущен

3. @TULSI Я полагаю, вы получили ответ. Я предполагал, что вам нужно запускать эту логику в цикле, пока у вас не появится статус RUNNING.

Ответ №3:

Приведенный ниже код сработал для меня, но вы можете заменить #tables на CTE и продолжить.

     create table #executables           (executable_id tinyint, execution_id tinyint, package_name nvarchar(20), executable_name nvarchar(20) )
    create table #executable_statistics (executable_id tinyint, execution_path nvarchar(100), execution_duration int, start_time datetime, end_time datetime)
    create table #executions            (execution_id tinyint, [status] tinyint)

    insert #executions (execution_id, [status]) values (1, 2)
    insert #executable_statistics (executable_id) values (1)
    insert #executables (execution_id, executable_id) values (1, 1)


    while 1 = 1
    begin
    select * into #results from (
        select
             e.package_name 
            ,e.execution_id
            ,e.executable_name 
            ,es.execution_path 
            ,es.execution_duration 
            ,es.start_time
            ,es.end_time
            ,execution_result = case ex.[status]
                when 1 then 'created' 
                when 2 then 'Running' 
                when 3 then 'canceled' 
                when 4 then 'failed' 
                when 5 then 'pending' 
                end
        from
            #executables e
            inner join #executable_statistics es on es.executable_id = e.executable_id
            inner join #executions ex on e.execution_id = ex.execution_id
        ) as t


    declare @execution_result varchar (100)
        set @execution_result = ''
     select @execution_result = execution_result from #results
     drop table #results

    if  @execution_result = 'Running'
        begin
            waitfor delay '00:00:30'
        end

    else return

    end

    --select * from #results

    --drop table #executables           
    --drop table #executable_statistics 
    --drop table #executions