web-dev-qa-db-ja.com

該当する条件が一度満たされた後、残りの日のためにジョブを停止する方法は?

IF条件をチェックするために5分ごとに実行するジョブがあります。条件がtrueの場合はメールが送信され、そうでない場合は何も行われません。

私の問題は、IF条件がtrueになると、それが1日中そのままになり、ジョブが5分ごとに実行されるため、5分ごとにメールを送信し続けることです。

メールが一度送信されたら、終日ジョブを停止する必要があります。そうする方法はありますか?

3

私は実際にmssqltips.comで同様の tip を作成しました。あなたの現在のケースでは、一般的なアイデアは次のようになります:

  1. ジョブの最後にステップを追加できます。プライマリジョブステップが成功すると、ジョブは最後のステップ(つまり、新しく追加されたステップ)を実行します。

  2. ジョブがプライマリステップで失敗した場合、ジョブは終了するだけで、最後に追加されたステップを実行する必要はありません。

  3. 最後のジョブステップでは、1つのことを行います。つまり、ジョブスケジュールの開始日を翌日に更新します。

    use msdb
    
    declare @active_date int, @sch_name varchar(128);
    
    select @sch_name=s.name
    from msdb.dbo.sysschedules s
    inner join msdb.dbo.sysjobschedules js
    on js.schedule_id = s.schedule_id
    and js.job_id = $(ESCAPE_NONE(JOBID));
    
    set @active_date = cast(replace(cast(cast(getdate()+1 as date) as varchar(10)), '-', '') as int);
    
    exec sp_update_schedule @name=@sch_name, @active_start_date= @active_date;
    

もちろん、あなたの仕事には1つの専用スケジュールしかないと思います。アプローチはすべて自己依存型であり、現在のジョブを管理するために追加の外部ジョブは必要ありません。

2
jyao

ジョブスケジュールを見て、スケジュールのIDを取得します。次の例では、スケジュールID 51を使用します。条件が最初にtrueであると判明したときに、ジョブのスケジュールを無効にすることができます。

USE [msdb]
GO
EXEC msdb.dbo.sp_update_schedule @schedule_id=51, 
    @enabled=0
GO

次に、その日の初めに(または条件が再びfalseになるときはいつでも)実行する別のジョブを設定して、それを有効にします。

USE [msdb]
GO
EXEC msdb.dbo.sp_update_schedule @schedule_id=51, 
    @enabled=1
GO

注意すべきことの1つ-スケジュールは複数のジョブで使用できるため、スケジュールが他のジョブでも使用されていないことを確認する必要があるだけです。したがって、スケジュールID 51が複数のジョブで使用されているかどうかを確認するには:

USE msdb
GO
SELECT * FROM sysjobschedules WHERE schedule_id = 51
1
Tony Hinkle

別のオプションは、単一の日時フラグ列を持つ小さなテーブルをどこかに作成することです。条件がTRUEと評価されたら、その値を現在の日時に更新します。

CAST(DatetimeFLAG AS DATE)が<CAST(GETDATE()AS DATE)でなければならないという条件をIFステートメントに追加する必要もあります。これは基本的に、同じ日付で再びTRUEと評価されるのを防ぎます。

このオプションは、スケジュールを変更したくない場合に機能します。

1
BCM

ジョブがストアドプロシージャを実行する場合、SPの先頭でジョブの履歴を確認し、ジョブが今日正常に実行された場合に戻ることができます。

IF EXISTS(SELECT 1
          FROM
            msdb.dbo.sysjobs as job
          JOIN
            msdb.dbo.sysjobhistory his
            ON job.job_id = his.job_id
          WHERE
            job.name = 'your job name'
            AND CAST(CAST(his.run_date AS char(8)) as date) = CAST(GETDATE() as date)
            AND his.run_status = 1)
BEGIN
  RETURN;
END
0
McNets

これがオプションの場合は、1日を通して定期的にジョブを実行するのではなく、ジョブを一度開始して、WHILEループにIF条件の確認を含めることを検討します。

それで、ジョブが毎日午前12時に開始されるとしましょうonce次のTSQLスクリプトの例はジョブステップ内に配置され、IF条件が満たされるまで、ジョブは実際にはcompleteになりません。

私の例では、現在の時刻が午後4時より大きいかどうかを確認しています。これはデモ用です。実際のコードは、IF条件を満たすものをチェックすることです。条件が満たされない場合は、単にWAITFOR DELAYし、WHILEループに進みます。私の例では、10秒ごとにIF条件をチェックしますが、任意の遅延を設定できます。

WHILEループに)チェックを含めて、ジョブが特定の時間を超えて実行されたかどうかを確認することもできます。その場合は、早期シャットダウンを示す警告メールを送信して、今日のジョブの実行を終了するWHILEループを終了できます。

DECLARE @IfConditionSatisfied BIT = 0

WHILE @IfConditionSatisfied = 0
BEGIN
    IF convert(TIME(0), GETDATE()) > '16:00:00' --simulate the criteria that satisfied the IF condition
    BEGIN
        SET @IfConditionSatisfied = 1
        --send emails, etc.
        --exit job
    END
    ELSE
    BEGIN
        WAITFOR DELAY '00:00:10' --wait for 10 seconds (or specify other hours, minutes, seconds)
    END
END
0
Scott Hodgin