IF条件をチェックするために5分ごとに実行するジョブがあります。条件がtrueの場合はメールが送信され、そうでない場合は何も行われません。
私の問題は、IF条件がtrueになると、それが1日中そのままになり、ジョブが5分ごとに実行されるため、5分ごとにメールを送信し続けることです。
メールが一度送信されたら、終日ジョブを停止する必要があります。そうする方法はありますか?
私は実際にmssqltips.comで同様の tip を作成しました。あなたの現在のケースでは、一般的なアイデアは次のようになります:
ジョブの最後にステップを追加できます。プライマリジョブステップが成功すると、ジョブは最後のステップ(つまり、新しく追加されたステップ)を実行します。
ジョブがプライマリステップで失敗した場合、ジョブは終了するだけで、最後に追加されたステップを実行する必要はありません。
最後のジョブステップでは、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つの専用スケジュールしかないと思います。アプローチはすべて自己依存型であり、現在のジョブを管理するために追加の外部ジョブは必要ありません。
ジョブスケジュールを見て、スケジュールの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
別のオプションは、単一の日時フラグ列を持つ小さなテーブルをどこかに作成することです。条件がTRUEと評価されたら、その値を現在の日時に更新します。
CAST(DatetimeFLAG AS DATE)が<CAST(GETDATE()AS DATE)でなければならないという条件をIFステートメントに追加する必要もあります。これは基本的に、同じ日付で再びTRUEと評価されるのを防ぎます。
このオプションは、スケジュールを変更したくない場合に機能します。
ジョブがストアドプロシージャを実行する場合、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
これがオプションの場合は、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