25

SQL Serverエージェントジョブを呼び出し、ジョブが正常に実行されたかどうかを返すストアドプロシージャが必要です。

これまでのところ私は

CREATE PROCEDURE MonthlyData
AS
EXEC msdb.dbo.sp_start_job N'MonthlyData'

WAITFOR DELAY '000:04:00'

EXEC msdb.dbo.sp_help_jobhistory @job_name = 'MonthlyData'
GO

どちらがジョブを開始しますか、ジョブが正常に実行されたかどうかを確認するための最良の方法は何ですか?

OKは編集を行い、WAITFOR DELAYを使用しました。これは、ジョブが通常3〜4分で実行され、4分を超えることはないためです。ジョブはありますが、より効率的な方法はありますか?

4

5 に答える 5

23

OPENROWSETコマンドの使用を許可されていないすべての人にとって、これは役立つかもしれません。私はここで私の解決策の始まりを見つけました:

http://social.msdn.microsoft.com/Forums/en-US/89659729-fea8-4df0-8057-79e0a437b658/dynamically-checking-job-status-with-tsql

これは、 msdb.dbo.sysjobactivityテーブルの一部の列が、ジョブが何らかの方法で終了した後に最初に入力されるという事実に依存しています。

-- Start job
DECLARE @job_name NVARCHAR(MAX) = 'JobName'
EXEC msdb.dbo.sp_start_job @job_name = @job_name


-- Wait for job to finish
DECLARE @job_history_id AS INT = NULL

WHILE @time_constraint = @ok
BEGIN
    SELECT TOP 1 @job_history_id = activity.job_history_id
    FROM msdb.dbo.sysjobs jobs
    INNER JOIN msdb.dbo.sysjobactivity activity ON activity.job_id = jobs.job_id
    WHERE jobs.name = @job_name
    ORDER BY activity.start_execution_date DESC

    IF @job_history_id IS NULL
    BEGIN
        WAITFOR DELAY '00:00:10'
        CONTINUE
    END
    ELSE
        BREAK
END


-- Check exit code
SELECT history.run_status
FROM msdb.dbo.sysjobhistory history
WHERE history.instance_id = @job_history_id

WHILEループの実行が許可されている期間をチェックすることをお勧めします。私はその部分を例から除外することにしました。

終了コードなどに関するMicrosoftのガイダンス: http ://technet.microsoft.com/en-us/library/ms174997.aspx

于 2013-10-23T15:56:09.960 に答える
21

クエリを実行できます。

EXEC msdb.dbo.sp_help_jobhistory 
    @job_name = N'MonthlyData'

列run_statusを返します。ステータスは次のとおりです。

 0 - Failed
 1 - Succeeded
 2 - Retry
 3 - Canceled         

MSDNの詳細情報

編集:あなたはあなたの仕事をポーリングして、それが実行されていることを確認したいかもしれません。この情報は、sp_help_jobプロシージャから取得できます。このプロシージャがステータスを返す場合4、ジョブはアイドル状態であることを意味します。次に、実行ステータスを確認しても安全です。

次のコードを使用してポーリングできます。

DECLARE @job_status INT
SELECT @job_status = current_execution_status FROM OPENROWSET('SQLNCLI', 'Server=.;Trusted_Connection=yes;','exec msdb.dbo.sp_help_job @job_name = ''NightlyBackups''')

WHILE @job_status <> 4
BEGIN
    WAITFOR DELAY '00:00:03'
    SELECT @job_status = current_execution_status FROM OPENROWSET('SQLNCLI', 'Server=.;Trusted_Connection=yes;','exec msdb.dbo.sp_help_job @job_name = ''NightlyBackups''')
END

EXEC msdb.dbo.sp_help_jobhistory 
    @job_name = N'NightlyBackups' ;
GO

このコードはステータスを確認し、3秒間待ってから、再試行します。ステータスが4になると、ジョブが完了したことがわかり、ジョブ履歴を安全に確認できます。

于 2012-09-03T13:49:21.060 に答える
2

これは、ジョブのステータスをチェックし、まだ実行されていない場合は実行するスクリプトです。

declare @xp_results table (
job_id                UNIQUEIDENTIFIER NOT NULL,
last_run_date         INT              NOT NULL,
last_run_time         INT              NOT NULL,
next_run_date         INT              NOT NULL,
next_run_time         INT              NOT NULL,
next_run_schedule_id  INT              NOT NULL,
requested_to_run      INT              NOT NULL, -- BOOL
request_source        INT              NOT NULL,
request_source_id     sysname          COLLATE database_default NULL,
running               INT              NOT NULL, -- BOOL
current_step          INT              NOT NULL,
current_retry_attempt INT              NOT NULL,
job_state             INT              NOT NULL)

DECLARE @job_id uniqueidentifier ;
select @job_id = job_id from msdb.dbo.sysjobs where name = 'Job1';
insert into @xp_results
EXEC master.dbo.xp_sqlagent_enum_jobs 1, sa, @job_id

select case when running = 1 then 'Currently Running' else '' end as running, 
case job_state 
    when 0 then 'Not Idle or Suspended'
    when 1 then 'Executing Job'
    when 2 then 'Waiting For Thread'
    when 3 then 'Between Retries'
    when 4 then 'Idle'
    when 5 then 'Suspended'
    when 6 then 'WaitingForStepToFinish'
    when 7 then 'PerformingCompletionActions'
end as job_state
from @xp_results

IF (select running from @xp_results) <> 1
    EXEC msdb.dbo.sp_start_job 'Job1'
于 2018-03-14T16:15:25.250 に答える
1

@lapponiandevilは、ここで最も使いやすい最良のソリューションを提供しますが、コードは必要以上に複雑であり、示されているコードで定義されていない@Time_constraint変数と@ok変数が必要なため、実際にはそのままでは機能しません。

これらはエージェントジョブのタイムアウトをサポートするためのものですが、これは必須ではありません。エージェントジョブステップは、独自のタイムアウト値を使用して構成でき、コードとは異なり、タイムアウト値を超えると適切にエラーになります。そのタイムアウト方法を使用した場合、プロセスの次のステップに進んだときに、ファントムエラーを探したり、待機していたエージェントジョブがまだ実行されていることに気付かなかったりする可能性があります。

コードを最小限に抑え、タイムアウト機能を削除するのが理想的だと思います。これが彼らの解決策に基づいて私が思いついたものです:

-- Start Agent Job
DECLARE @JobName NVARCHAR(128) = 'My Agent Job Name'
   EXEC msdb.dbo.sp_start_job @JobName

-- Wait for Agent Job to finish
DECLARE @HistoryID AS INT = NULL
  WHILE @HistoryID IS NULL
  BEGIN
        --Read most recent Job History ID for the specified Agent Job name
            SELECT TOP 1 @HistoryID = b.job_history_id
              FROM msdb.dbo.sysjobs a
        INNER JOIN msdb.dbo.sysjobactivity b ON b.job_id = a.job_id
             WHERE a.name = @JobName
          ORDER BY b.Start_execution_date DESC
        --If Job is still running (Job History ID = NULL), wait 3 seconds
                IF @HistoryID IS NULL WAITFOR DELAY '00:00:03'
    END

-- Check Agent Job exit code to make sure it succeeded
     IF (SELECT run_status 
           FROM msdb.dbo.sysjobhistory 
          WHERE instance_id = @HistoryID) <> 1 
  THROW 69000, 'Child Agent Job failure', 1;  
于 2021-01-21T14:59:06.823 に答える
0

少し遅れるかもしれませんが、次のクエリが機能することがわかりました。実行時間と実行終了時間を示します。ステータスを取得するように変更することもできます。

SELECT 
    job.name, 
    job.job_id, 
    job.originating_server, 
    activity.run_requested_date, 
    activity.stop_execution_date, 
    DATEDIFF( SECOND, activity.run_requested_date, activity.stop_execution_date ) as Elapsed 
FROM msdb.dbo.sysjobs_view job 
JOIN msdb.dbo.sysjobactivity activity ON job.job_id = activity.job_id 
JOIN msdb.dbo.syssessions sess ON sess.session_id = activity.session_id 
JOIN 
( 
    SELECT 
    MAX( agent_start_date ) AS max_agent_start_date 
    FROM 
    msdb.dbo.syssessions 
) sess_max 
ON sess.agent_start_date = sess_max.max_agent_start_date 
WHERE run_requested_date IS NOT NULL 
--AND stop_execution_date IS NULL 
AND job.name = @JobName
于 2015-07-23T14:18:43.707 に答える