ジョブをスケジュールするストアドプロシージャがあります。このジョブが完了するまでに時間がかかります(約30〜40分)。このジョブのステータスを知る必要があります。以下の詳細は私を助けます
1)将来の時間にスケジュールされ、まだ開始されていないすべてのジョブのリストを表示する方法
2)実行中のジョブのリストと、それらが実行されているときからの期間を表示する方法
3)ジョブが正常に完了したか、エラーのために途中で停止したかどうかを確認する方法。
システムストアドプロシージャsp_help_jobを使用してみてください。これにより、ジョブ、そのステップ、スケジュール、サーバーに関する情報が返されます。例えば
EXEC msdb.dbo.sp_help_job @Job_name = 'Your Job Name'
SQL Books Online 返されるレコードに関する多くの情報を含める必要があります。
複数のジョブに関する情報を返すには、ジョブに関するさまざまな情報を保持する次のシステムテーブルを照会してみてください。
それらの名前は、一目瞭然です(ジョブが最後に実行されたときと結果に関する情報を保持するSysJobServersを除く)。
繰り返しになりますが、フィールドに関する情報はMSDNで参照できます。たとえば、 SysJobs のページをご覧ください
このページのT-SQLはどれも正確に機能しないことを指摘したいのですが、それらのどれもsyssessionsテーブルに参加していないため、現在のセッションのため、誤検知が含まれる可能性があります。
参照用にこれを参照してください: 終了日がnullのジョブがあるとはどういう意味ですか?
これを検証するには、sp_help_jobactivityプロシージャをmsdbで分析することもできます。
これはSOの古いメッセージであることに気づきましたが、問題があるため、このメッセージは部分的にしか役に立ちませんでした。
SELECT
job.name,
job.job_id,
job.originating_server,
activity.run_requested_date,
DATEDIFF( SECOND, activity.run_requested_date, GETDATE() ) 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
これは、実行中のジョブを取得するために使用しているものです(主に、おそらくハングしているジョブを強制終了できます)。
SELECT
job.Name, job.job_ID
,job.Originating_Server
,activity.run_requested_Date
,datediff(minute, activity.run_requested_Date, getdate()) AS Elapsed
FROM
msdb.dbo.sysjobs_view job
INNER JOIN msdb.dbo.sysjobactivity activity
ON (job.job_id = activity.job_id)
WHERE
run_Requested_date is not null
AND stop_execution_date is null
AND job.name like 'Your Job Prefix%'
ティムが言ったように、MSDN/BOLのドキュメントはsysjobsXテーブルの内容に関してかなり良いです。 MSDBのテーブルであることを思い出してください。
-- Microsoft SQL Server 2008 Standard Edition:
IF EXISTS(SELECT 1
FROM msdb.dbo.sysjobs J
JOIN msdb.dbo.sysjobactivity A
ON A.job_id=J.job_id
WHERE J.name=N'Your Job Name'
AND A.run_requested_date IS NOT NULL
AND A.stop_execution_date IS NULL
)
PRINT 'The job is running!'
ELSE
PRINT 'The job is not running.'
詳細を取得するために、さまざまな方法でmsdbを照会できます。
少ない
select job.Name, job.job_ID, job.Originating_Server,activity.run_requested_Date,
datediff(minute, activity.run_requested_Date, getdate()) as Elapsed
from msdb.dbo.sysjobs_view job
inner join msdb.dbo.sysjobactivity activity on (job.job_id = activity.job_id)
where run_Requested_date is not null
and stop_execution_date is null
and job.name like 'Your Job Prefix%'
これは古い質問ですが、SQL Serverのジョブのステータスを確認する必要があるような状況がありました。多くの人がsysjobactivityテーブルに言及し、素晴らしいMSDNドキュメントを指摘しました。ただし、サーバーで定義されているすべてのジョブのステータスを提供する ジョブアクティビティモニター も強調表示します。
これにより、前回の実行ステータス/時間が表示されます。実行中の場合は、現在の実行時間、ステップ番号/情報、およびSPID(SPIDが関連付けられている場合)が表示されます。また、未解決のユーザーアカウントに対してNT SID形式に変換する有効/無効およびジョブユーザーも表示されます。
CREATE TABLE #list_running_SQL_jobs
(
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
, request_source INT NOT NULL
, request_source_id sysname NULL
, running INT NOT NULL
, current_step INT NOT NULL
, current_retry_attempt INT NOT NULL
, job_state INT NOT NULL
);
DECLARE @sqluser NVARCHAR(128)
, @is_sysadmin INT;
SELECT @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0);
DECLARE read_sysjobs_for_running CURSOR FOR
SELECT DISTINCT SUSER_SNAME(owner_sid)FROM msdb.dbo.sysjobs;
OPEN read_sysjobs_for_running;
FETCH NEXT FROM read_sysjobs_for_running
INTO @sqluser;
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO #list_running_SQL_jobs
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @sqluser;
FETCH NEXT FROM read_sysjobs_for_running
INTO @sqluser;
END;
CLOSE read_sysjobs_for_running;
DEALLOCATE read_sysjobs_for_running;
SELECT j.name
, 'Enbld' = CASE j.enabled
WHEN 0
THEN 'no'
ELSE 'YES'
END
, '#Min' = DATEDIFF(MINUTE, a.start_execution_date, ISNULL(a.stop_execution_date, GETDATE()))
, 'Status' = CASE
WHEN a.start_execution_date IS NOT NULL
AND a.stop_execution_date IS NULL
THEN 'Executing'
WHEN h.run_status = 0
THEN 'FAILED'
WHEN h.run_status = 2
THEN 'Retry'
WHEN h.run_status = 3
THEN 'Canceled'
WHEN h.run_status = 4
THEN 'InProg'
WHEN h.run_status = 1
THEN 'Success'
ELSE 'Idle'
END
, r.current_step
, spid = p.session_id
, owner = ISNULL(SUSER_SNAME(j.owner_sid), 'S-' + CONVERT(NVARCHAR(12), CONVERT(BIGINT, UNICODE(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 1))) - CONVERT(BIGINT, 256) * CONVERT(BIGINT, UNICODE(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 1)) / 256)) + '-' + CONVERT(NVARCHAR(12), UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 4), 1)) / 256 + CONVERT(BIGINT, NULLIF(UNICODE(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 1)) / 256, 0)) - CONVERT(BIGINT, UNICODE(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 1)) / 256)) + ISNULL('-' + CONVERT(NVARCHAR(12), CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 5), 1))) + CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 6), 1))) * CONVERT(BIGINT, 65536) + CONVERT(BIGINT, NULLIF(SIGN(LEN(CONVERT(NVARCHAR(256), j.owner_sid)) - 6), -1)) * 0), '') + ISNULL('-' + CONVERT(NVARCHAR(12), CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 7), 1))) + CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 8), 1))) * CONVERT(BIGINT, 65536) + CONVERT(BIGINT, NULLIF(SIGN(LEN(CONVERT(NVARCHAR(256), j.owner_sid)) - 8), -1)) * 0), '') + ISNULL('-' + CONVERT(NVARCHAR(12), CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 9), 1))) + CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 10), 1))) * CONVERT(BIGINT, 65536) + CONVERT(BIGINT, NULLIF(SIGN(LEN(CONVERT(NVARCHAR(256), j.owner_sid)) - 10), -1)) * 0), '') + ISNULL('-' + CONVERT(NVARCHAR(12), CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 11), 1))) + CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 12), 1))) * CONVERT(BIGINT, 65536) + CONVERT(BIGINT, NULLIF(SIGN(LEN(CONVERT(NVARCHAR(256), j.owner_sid)) - 12), -1)) * 0), '') + ISNULL('-' + CONVERT(NVARCHAR(12), CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 13), 1))) + CONVERT(BIGINT, UNICODE(RIGHT(LEFT(CONVERT(NVARCHAR(256), j.owner_sid), 14), 1))) * CONVERT(BIGINT, 65536) + CONVERT(BIGINT, NULLIF(SIGN(LEN(CONVERT(NVARCHAR(256), j.owner_sid)) - 14), -1)) * 0), '')) --SHOW as NT SID when unresolved
, a.start_execution_date
, a.stop_execution_date
, t.subsystem
, t.step_name
FROM msdb.dbo.sysjobs j
LEFT OUTER JOIN (SELECT DISTINCT * FROM #list_running_SQL_jobs) r
ON j.job_id = r.job_id
LEFT OUTER JOIN msdb.dbo.sysjobactivity a
ON j.job_id = a.job_id
AND a.start_execution_date IS NOT NULL
--AND a.stop_execution_date IS NULL
AND NOT EXISTS
(
SELECT *
FROM msdb.dbo.sysjobactivity at
WHERE at.job_id = a.job_id
AND at.start_execution_date > a.start_execution_date
)
LEFT OUTER JOIN sys.dm_exec_sessions p
ON p.program_name LIKE 'SQLAgent%0x%'
AND j.job_id = SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 7, 2) + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 5, 2) + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 3, 2) + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 1, 2) + '-' + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 11, 2) + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 9, 2) + '-' + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 15, 2) + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 13, 2) + '-' + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 17, 4) + '-' + SUBSTRING(SUBSTRING(p.program_name, CHARINDEX('0x', p.program_name) + 2, 32), 21, 12)
LEFT OUTER JOIN msdb.dbo.sysjobhistory h
ON j.job_id = h.job_id
AND h.instance_id = a.job_history_id
LEFT OUTER JOIN msdb.dbo.sysjobsteps t
ON t.job_id = j.job_id
AND t.step_id = r.current_step
ORDER BY 1;
DROP TABLE #list_running_SQL_jobs;
これらの詳細の表示方法を指定していません。
一目で Server Management Studio を確認することをお勧めします。
ジョブと現在のステータスは、ジョブの下のSQL Serverエージェント部分で確認できます。ジョブを選択すると、プロパティページにジョブ履歴へのリンクが表示されます。このページでは、開始時刻と終了時刻、エラーがある場合、エラーの原因となったステップなどを確認できます。
アラートと通知を指定して、ジョブが正常に終了したか失敗したときに、電子メールで送信したり、ページングしたりできます。
ジョブアクティビティモニターはありますが、実際には使用していません。試してみることができます。
T-SQLで確認したい場合、どうすればそれができるかわかりません。
上記のタスクは機能しますが、msdb.dbo.sysjobactivityに多くのレコードがありますrun_Requested_dateはnullではなく、stop_execution_dateはnull ----で、ジョブは現在実行されていません。
次のスクリプトを実行して、すべての偽のエントリを消去することをお勧めします(その時点でジョブが実行されていないことを確認してください)。
SQL2008:
delete activity
from msdb.dbo.sysjobs_view job
inner join msdb.dbo.sysjobactivity activity on job.job_id = activity.job_id
where
activity.run_Requested_date is not null
and activity.stop_execution_date is null
私が見つけた最も簡単な方法は、ストアドプロシージャを作成することでした。 「JobName」を入力して、「Go」をクリックします。
/*-----------------------------------------------------------------------------------------------------------
Document Title: usp_getJobStatus
Purpose: Finds a Current Jobs Run Status
Input Example: EXECUTE usp_getJobStatus 'MyJobName'
-------------------------------------------------------------------------------------------------------------*/
IF OBJECT_ID ( 'usp_getJobStatus','P' ) IS NOT NULL
DROP PROCEDURE usp_getJobStatus;
GO
CREATE PROCEDURE usp_getJobStatus
@JobName NVARCHAR (1000)
AS
IF OBJECT_ID('TempDB..#JobResults','U') IS NOT NULL DROP TABLE #JobResults
CREATE TABLE #JobResults ( 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,
Request_Source INT NOT NULL,
Request_Source_id SYSNAME
COLLATE Database_Default NULL,
Running INT NOT NULL,
Current_Step INT NOT NULL,
Current_Retry_Attempt INT NOT NULL,
Job_State INT NOT NULL )
INSERT #JobResults
EXECUTE master.dbo.xp_sqlagent_enum_jobs 1, '';
SELECT job.name AS [Job_Name],
( SELECT MAX(CAST( STUFF(STUFF(CAST(jh.run_date AS VARCHAR),7,0,'-'),5,0,'-') + ' ' +
STUFF(STUFF(REPLACE(STR(jh.run_time,6,0),' ','0'),5,0,':'),3,0,':') AS DATETIME))
FROM msdb.dbo.sysjobs AS j
INNER JOIN msdb.dbo.sysjobhistory AS jh
ON jh.job_id = j.job_id AND jh.step_id = 0
WHERE j.[name] LIKE '%' + @JobName + '%'
GROUP BY j.[name] ) AS [Last_Completed_DateTime],
( SELECT TOP 1 start_execution_date
FROM msdb.dbo.sysjobactivity
WHERE job_id = r.job_id
ORDER BY start_execution_date DESC ) AS [Job_Start_DateTime],
CASE
WHEN r.running = 0 THEN
CASE
WHEN jobInfo.lASt_run_outcome = 0 THEN 'Failed'
WHEN jobInfo.lASt_run_outcome = 1 THEN 'Success'
WHEN jobInfo.lASt_run_outcome = 3 THEN 'Canceled'
ELSE 'Unknown'
END
WHEN r.job_state = 0 THEN 'Success'
WHEN r.job_state = 4 THEN 'Success'
WHEN r.job_state = 5 THEN 'Success'
WHEN r.job_state = 1 THEN 'In Progress'
WHEN r.job_state = 2 THEN 'In Progress'
WHEN r.job_state = 3 THEN 'In Progress'
WHEN r.job_state = 7 THEN 'In Progress'
ELSE 'Unknown' END AS [Run_Status_Description]
FROM #JobResults AS r
LEFT OUTER JOIN msdb.dbo.sysjobservers AS jobInfo
ON r.job_id = jobInfo.job_id
INNER JOIN msdb.dbo.sysjobs AS job
ON r.job_id = job.job_id
WHERE job.[enabled] = 1
AND job.name LIKE '%' + @JobName + '%'
SELECT sj.name
FROM msdb..sysjobactivity aj
JOIN msdb..sysjobs sj
on sj.job_id = aj.job_id
WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running
AND aj.start_execution_date IS NOT NULL -- job is currently running
AND sj.name = '<your Job Name>'
AND NOT EXISTS( -- make sure this is the most recent run
select 1
from msdb..sysjobactivity new
where new.job_id = aj.job_id
and new.start_execution_date > aj.start_execution_date ) )
print 'running'
ジョブの1つが実行されると、サーバーの1つでMSDBテーブル(上記のコード)を照会する際に問題が発生しましたが、そうではありませんでした。実行ステータスを返すシステムストアドプロシージャがありますが、エラーなしでinsert execステートメントを実行することはできません。その中には、INSERT EXECステートメントで使用できる別のシステムストアドプロシージャがあります。
INSERT INTO #Job
EXEC master.dbo.xp_sqlagent_enum_jobs 1,dbo
そしてそれをロードするテーブル:
CREATE TABLE #Job
(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)
;WITH CTE_JobStatus
AS (
SELECT DISTINCT NAME AS [JobName]
,s.step_id
,s.step_name
,CASE
WHEN [Enabled] = 1
THEN 'Enabled'
ELSE 'Disabled'
END [JobStatus]
,CASE
WHEN SJH.run_status = 0
THEN 'Failed'
WHEN SJH.run_status = 1
THEN 'Succeeded'
WHEN SJH.run_status = 2
THEN 'Retry'
WHEN SJH.run_status = 3
THEN 'Cancelled'
WHEN SJH.run_status = 4
THEN 'In Progress'
ELSE 'Unknown'
END [JobOutcome]
,CONVERT(VARCHAR(8), sjh.run_date) [RunDate]
,CONVERT(VARCHAR(8), STUFF(STUFF(CONVERT(TIMESTAMP, RIGHT('000000' + CONVERT(VARCHAR(6), sjh.run_time), 6)), 3, 0, ':'), 6, 0, ':')) RunTime
,RANK() OVER (
PARTITION BY s.step_name ORDER BY sjh.run_date DESC
,sjh.run_time DESC
) AS rn
,SJH.run_status
FROM msdb..SYSJobs sj
INNER JOIN msdb..SYSJobHistory sjh ON sj.job_id = sjh.job_id
INNER JOIN msdb.dbo.sysjobsteps s ON sjh.job_id = s.job_id
AND sjh.step_id = s.step_id
WHERE (sj.NAME LIKE 'JOB NAME')
AND sjh.run_date = CONVERT(CHAR, getdate(), 112)
)
SELECT *
FROM CTE_JobStatus
WHERE rn = 1
AND run_status NOT IN (1,4)