web-dev-qa-db-ja.com

SQLスケジュールされたジョブクエリ、最後の実行の期間?

以前はこれを使用していました SQLエージェントジョブ、ドキュメント化方法 すべてのSQLスケジュールジョブに関する情報を取得します。

各ジョブの最後の実行の期間を確認するにはどうすればよいですか?私は秒、分、そして時間を必要とします(願わくばそうではありませんが、私は恐れています)。

誰かが私がこれをクエリする方法についていくつかの洞察を与えることができますか?

11
MAW74656

999時間より長く実行されるジョブがないことを前提とすると、これは良い出発点になるはずです。

SELECT
    j.name,
    h.run_status,
    durationHHMMSS = STUFF(STUFF(REPLACE(STR(h.run_duration,7,0),
        ' ','0'),4,0,':'),7,0,':'),
    [start_date] = CONVERT(DATETIME, RTRIM(run_date) + ' '
        + STUFF(STUFF(REPLACE(STR(RTRIM(h.run_time),6,0),
        ' ','0'),3,0,':'),6,0,':'))
FROM
    msdb.dbo.sysjobs AS j
INNER JOIN
    (
        SELECT job_id, instance_id = MAX(instance_id)
            FROM msdb.dbo.sysjobhistory
            GROUP BY job_id
    ) AS l
    ON j.job_id = l.job_id
INNER JOIN
    msdb.dbo.sysjobhistory AS h
    ON h.job_id = l.job_id
    AND h.instance_id = l.instance_id
ORDER BY
    CONVERT(INT, h.run_duration) DESC,
    [start_date] DESC;
20
Aaron Bertrand

アーロン、スクリプトにいくつかの調整を加えました。これには、次のスケジュールされた実行時間(開始日はスケジュールの最初の開始日であり、必ずしもジョブの次の開始日ではありません)、およびその他のさまざまなチェックが含まれます。フレームワークをありがとう。確かに非常に役立つ出発点です!

私はまた、古くて良いものからいくつかの論理を取りました( ここ )。

USE msdb
Go


SELECT j.Name AS 'Job Name', 
    '"' + NULLIF(j.Description, 'No description available.') + '"' AS 'Description',
    SUSER_SNAME(j.owner_sid) AS 'Job Owner',
    (SELECT COUNT(step_id) FROM dbo.sysjobsteps WHERE job_id = j.job_id) AS 'Number of Steps',
    (SELECT COUNT(step_id) FROM dbo.sysjobsteps WHERE job_id = j.job_id AND command LIKE '%xp_cmdshell%') AS 'has_xpcmdshell',
    (SELECT COUNT(step_id) FROM dbo.sysjobsteps WHERE job_id = j.job_id AND command LIKE '%msdb%job%') AS 'has_jobstartstopupdate',
    (SELECT COUNT(step_id) FROM dbo.sysjobsteps WHERE job_id = j.job_id AND command LIKE '%ftp%') AS 'has_ftp',
    'Job Enabled' = CASE j.Enabled
        WHEN 1 THEN 'Yes'
        WHEN 0 THEN 'No'
    END,
    'Frequency' = CASE s.freq_type
        WHEN 1 THEN 'Once'
        WHEN 4 THEN 'Daily'
        WHEN 8 THEN 'Weekly'
        WHEN 16 THEN 'Monthly'
        WHEN 32 THEN 'Monthly relative'
        WHEN 64 THEN 'When SQLServer Agent starts'
    END, 
    CASE(s.freq_subday_interval)
        WHEN 0 THEN 'Once'
        ELSE cast('Every ' 
                + right(s.freq_subday_interval,2) 
                + ' '
                +     CASE(s.freq_subday_type)
                            WHEN 1 THEN 'Once'
                            WHEN 4 THEN 'Minutes'
                            WHEN 8 THEN 'Hours'
                        END as char(16))
    END as 'Subday Frequency',
    'Next Start Date'= CONVERT(DATETIME, RTRIM(NULLIF(js.next_run_date, 0)) + ' '
        + STUFF(STUFF(REPLACE(STR(RTRIM(js.next_run_time),6,0),
        ' ','0'),3,0,':'),6,0,':')),
    'Max Duration' = STUFF(STUFF(REPLACE(STR(maxdur.run_duration,7,0),
        ' ','0'),4,0,':'),7,0,':'),
    'Last Run Duration' = STUFF(STUFF(REPLACE(STR(lastrun.run_duration,7,0),
        ' ','0'),4,0,':'),7,0,':'),
    'Last Start Date' = CONVERT(DATETIME, RTRIM(lastrun.run_date) + ' '
        + STUFF(STUFF(REPLACE(STR(RTRIM(lastrun.run_time),6,0),
        ' ','0'),3,0,':'),6,0,':')),
    'Last Run Message' = lastrun.message
FROM dbo.sysjobs j
LEFT OUTER JOIN dbo.sysjobschedules js
    ON j.job_id = js.job_id
LEFT OUTER JOIN dbo.sysschedules s
    ON js.schedule_id = s.schedule_id 
LEFT OUTER JOIN (SELECT job_id, max(run_duration) AS run_duration
        FROM dbo.sysjobhistory
        GROUP BY job_id) maxdur
ON j.job_id = maxdur.job_id
-- INNER JOIN -- Swap Join Types if you don't want to include jobs that have never run
LEFT OUTER JOIN
    (SELECT j1.job_id, j1.run_duration, j1.run_date, j1.run_time, j1.message
    FROM dbo.sysjobhistory j1
    WHERE instance_id = (SELECT MAX(instance_id) 
                         FROM dbo.sysjobhistory j2 
                         WHERE j2.job_id = j1.job_id)) lastrun
    ON j.job_id = lastrun.job_id
ORDER BY [Job Name]
11
John Eisbrener

SQL Serverエージェント(ジョブ関連)情報を取得するためのスクリプト:

スクリプトは以下の情報を提供します:

  • SSMSの[SQLServerエージェントのジョブのプロパティ]ウィンドウにもあるジョブレベルのセットアップと構成の情報。

  • SQL Serverエージェントジョブの最後/最新の実行の詳細と、ジョブが次に実行される時刻(スケジュールされている場合)。この情報は、SSMSの[ジョブ履歴]/[ジョブアクティビティモニター]ウィンドウにも表示されます。

  • ジョブステップレベルのセットアップと構成の情報。これは、SSMSの[ジョブステップのプロパティ]ウィンドウにもあります。
  • ジョブステップの最後/最新の実行の詳細。この情報は、SSMSの[ジョブ履歴]/[ログファイルビューア]ウィンドウにも表示されます。
  • SQL Serverで作成/使用可能なスケジュールのリストと、各スケジュールの詳細(発生、繰り返し、頻度など)。
use msdb
go
SELECT 
    [sJOB].[name] AS [JobName]
    , [sDBP].[name] AS [JobOwner]
    , [sCAT].[name] AS [JobCategory]
  , [sJOB].[description] AS [JobDescription]
    , [sJSTP].[step_id] AS [JobStartStepNo]
    , [sJSTP].[step_name] AS [JobStartStepName]
    , [sJOB].[date_created] AS [JobCreatedOn]
    , [sJOB].[date_modified] AS [JobLastModifiedOn]
  , CASE [sJOB].[enabled]
        WHEN 1 THEN 'Yes'
        WHEN 0 THEN 'No'
      END AS [IsEnabled]
       , CASE
          WHEN [sSCH].[schedule_uid] IS NULL THEN 'No'
          ELSE 'Yes'
          END AS [IsScheduled]
    , CASE 
        WHEN [freq_type] = 64 THEN 'Start automatically when SQL Server Agent starts'
        WHEN [freq_type] = 128 THEN 'Start whenever the CPUs become idle'
        WHEN [freq_type] IN (4,8,16,32) THEN 'Recurring'
        WHEN [freq_type] = 1 THEN 'One Time'
      END [ScheduleType]
    , CASE [freq_type]
        WHEN 1 THEN 'One Time'
        WHEN 4 THEN 'Daily'
        WHEN 8 THEN 'Weekly'
        WHEN 16 THEN 'Monthly'
        WHEN 32 THEN 'Monthly - Relative to Frequency Interval'
        WHEN 64 THEN 'Start automatically when SQL Server Agent starts'
        WHEN 128 THEN 'Start whenever the CPUs become idle'
      END [Occurrence]
    , CASE [freq_type]
        WHEN 4 THEN 'Occurs every ' + CAST([freq_interval] AS VARCHAR(3)) + ' day(s)'
        WHEN 8 THEN 'Occurs every ' + CAST([freq_recurrence_factor] AS VARCHAR(3)) 
                    + ' week(s) on '
                    + CASE WHEN [freq_interval] & 1 = 1 THEN 'Sunday' ELSE '' END
                    + CASE WHEN [freq_interval] & 2 = 2 THEN ', Monday' ELSE '' END
                    + CASE WHEN [freq_interval] & 4 = 4 THEN ', Tuesday' ELSE '' END
                    + CASE WHEN [freq_interval] & 8 = 8 THEN ', Wednesday' ELSE '' END
                    + CASE WHEN [freq_interval] & 16 = 16 THEN ', Thursday' ELSE '' END
                    + CASE WHEN [freq_interval] & 32 = 32 THEN ', Friday' ELSE '' END
                    + CASE WHEN [freq_interval] & 64 = 64 THEN ', Saturday' ELSE '' END
        WHEN 16 THEN 'Occurs on Day ' + CAST([freq_interval] AS VARCHAR(3)) 
                     + ' of every '
                     + CAST([freq_recurrence_factor] AS VARCHAR(3)) + ' month(s)'
        WHEN 32 THEN 'Occurs on '
                     + CASE [freq_relative_interval]
                        WHEN 1 THEN 'First'
                        WHEN 2 THEN 'Second'
                        WHEN 4 THEN 'Third'
                        WHEN 8 THEN 'Fourth'
                        WHEN 16 THEN 'Last'
                       END
                     + ' ' 
                     + CASE [freq_interval]
                        WHEN 1 THEN 'Sunday'
                        WHEN 2 THEN 'Monday'
                        WHEN 3 THEN 'Tuesday'
                        WHEN 4 THEN 'Wednesday'
                        WHEN 5 THEN 'Thursday'
                        WHEN 6 THEN 'Friday'
                        WHEN 7 THEN 'Saturday'
                        WHEN 8 THEN 'Day'
                        WHEN 9 THEN 'Weekday'
                        WHEN 10 THEN 'Weekend day'
                       END
                     + ' of every ' + CAST([freq_recurrence_factor] AS VARCHAR(3)) 
                     + ' month(s)'
      END AS [Recurrence]
    , CASE [freq_subday_type]
        WHEN 1 THEN 'Occurs once at ' 
                    + STUFF(
                 STUFF(RIGHT('000000' + CAST([active_start_time] AS VARCHAR(6)), 6)
                                , 3, 0, ':')
                            , 6, 0, ':')
        WHEN 2 THEN 'Occurs every ' 
                    + CAST([freq_subday_interval] AS VARCHAR(3)) + ' Second(s) between ' 
                    + STUFF(
                   STUFF(RIGHT('000000' + CAST([active_start_time] AS VARCHAR(6)), 6)
                                , 3, 0, ':')
                            , 6, 0, ':')
                    + ' & ' 
                    + STUFF(
                    STUFF(RIGHT('000000' + CAST([active_end_time] AS VARCHAR(6)), 6)
                                , 3, 0, ':')
                            , 6, 0, ':')
        WHEN 4 THEN 'Occurs every ' 
                    + CAST([freq_subday_interval] AS VARCHAR(3)) + ' Minute(s) between ' 
                    + STUFF(
                   STUFF(RIGHT('000000' + CAST([active_start_time] AS VARCHAR(6)), 6)
                                , 3, 0, ':')
                            , 6, 0, ':')
                    + ' & ' 
                    + STUFF(
                    STUFF(RIGHT('000000' + CAST([active_end_time] AS VARCHAR(6)), 6)
                                , 3, 0, ':')
                            , 6, 0, ':')
        WHEN 8 THEN 'Occurs every ' 
                    + CAST([freq_subday_interval] AS VARCHAR(3)) + ' Hour(s) between ' 
                    + STUFF(
                    STUFF(RIGHT('000000' + CAST([active_start_time] AS VARCHAR(6)), 6)
                                , 3, 0, ':')
                            , 6, 0, ':')
                    + ' & ' 
                    + STUFF(
                    STUFF(RIGHT('000000' + CAST([active_end_time] AS VARCHAR(6)), 6)
                                , 3, 0, ':')
                            , 6, 0, ':')
      END [Frequency]

    , [sSCH].[name] AS [JobScheduleName]
    --,[sJSTP].database_name
   , Last_Run = CONVERT(DATETIME, RTRIM(run_date) + ' '
        + STUFF(STUFF(REPLACE(STR(RTRIM(h.run_time),6,0),
        ' ','0'),3,0,':'),6,0,':'))
  , case [sJSTP].Last_run_outcome
          When 0 then 'Failed'
          when 1 then 'Succeeded'
          When 2 then 'Retry'
          When 3 then 'Canceled'
          When 5 then 'Unknown'
   End as Last_Run_Status

  ,Last_Run_Duration_HHMMSS = STUFF(STUFF(REPLACE(STR([sJSTP].last_run_duration,7,0),
        ' ','0'),4,0,':'),7,0,':')
    , Max_Duration = STUFF(STUFF(REPLACE(STR(l.run_duration,7,0),
        ' ','0'),4,0,':'),7,0,':')
  , Next_Run= CONVERT(DATETIME, RTRIM(NULLIF([sJOBSCH].next_run_date, 0)) + ' '
        + STUFF(STUFF(REPLACE(STR(RTRIM([sJOBSCH].next_run_time),6,0),
        ' ','0'),3,0,':'),6,0,':'))
    , CASE [sJOB].[delete_level]
        WHEN 0 THEN 'Never'
        WHEN 1 THEN 'On Success'
        WHEN 2 THEN 'On Failure'
        WHEN 3 THEN 'On Completion'
      END AS [JobDeletionCriterion]

    , [sSVR].[name] AS [OriginatingServerName]
    ,[sJSTP].subsystem
    ,[sJSTP].command
  ,h.message

FROM
    [msdb].[dbo].[sysjobs] AS [sJOB]
    LEFT JOIN [msdb].[sys].[servers] AS [sSVR]
        ON [sJOB].[originating_server_id] = [sSVR].[server_id]
    LEFT JOIN [msdb].[dbo].[syscategories] AS [sCAT]
        ON [sJOB].[category_id] = [sCAT].[category_id]
    LEFT JOIN [msdb].[dbo].[sysjobsteps] AS [sJSTP]
        ON [sJOB].[job_id] = [sJSTP].[job_id]
        AND [sJOB].[start_step_id] = [sJSTP].[step_id]
    LEFT JOIN [msdb].[sys].[database_principals] AS [sDBP]
        ON [sJOB].[owner_sid] = [sDBP].[sid]
    LEFT JOIN [msdb].[dbo].[sysjobschedules] AS [sJOBSCH]
        ON [sJOB].[job_id] = [sJOBSCH].[job_id]
    LEFT JOIN [msdb].[dbo].[sysschedules] AS [sSCH]
        ON [sJOBSCH].[schedule_id] = [sSCH].[schedule_id]

        left JOIN
    (
        SELECT job_id, instance_id = MAX(instance_id),max(run_duration) AS run_duration
            FROM msdb.dbo.sysjobhistory
            GROUP BY job_id
    ) AS l
    ON sJOB.job_id = l.job_id
left JOIN
    msdb.dbo.sysjobhistory AS h
    ON h.job_id = l.job_id
    AND h.instance_id = l.instance_id
ORDER BY [JobName]

以下は、上記のクエリから返される各フィールドの簡単な説明です:

  1. [JobName]:SQLServerエージェントジョブの名前。
  2. [JobOwner]:ジョブの所有者。
  3. [JobCategory]:レプリケーションスナップショット、データベースメンテナンス、ログ配布など、ジョブが属するカテゴリ。
  4. [JobDescription]:ジョブの説明。
  5. [JobStartStepNo]:ジョブの開始を設定するステップ番号。 SQL Serverでは、ジョブ内に複数のステップを含めることができ、ユーザーが開始したいステップからジョブを開始するように設定できます。
  6. [JobStartStepName]:ジョブの開始が設定されているステップの名前。
  7. [JobCreatedOn]:ジョブが作成された日時。
  8. [JobLastModifiedOn]:ジョブが最後に変更された日時。
  9. [IsEnabled]:ジョブが有効か無効かを表すインジケーター。
  10. [IsScheduled]:ジョブがスケジュールされているかどうかを表すインジケーター。ジョブは、指定された曜日の指定された時間に実行するようにスケジュールすることも、T-SQLなどのコードを介して呼び出すこともできます。
  11. [ScheduleType]:スケジュールのタイプ。
  12. [オカレンス]:日次、週次、月次などのスケジュールのオカレンス。
  13. [繰り返し]:特定の曜日、特定の曜日、週数などのスケジュールの繰り返し。
  14. [頻度]:ジョブが実行されるようにスケジュールされた日に実行される頻度:スケジュールされた日に1回だけ発生する、スケジュールされた日に2時間ごとに発生するなど。指定された開始時間と終了時間。
  15. [JobScheduleName]:ジョブに関連付けられているスケジュールの名前。 SQL Serverでは、複数のスケジュールを1つのジョブに関連付けることができます。その場合、上記のクエリは、各ジョブに関連付けられたスケジュールごとに1つの行を返します。
  16. [Last_Run]:ジョブが最後に実行された日時(最新の実行に対応)。
  17. [Last_Run_Status]:最後のジョブ実行のステータスまたは結果。
  18. [Last_Run_Duration_HHMMSS]:時間:分:秒の形式で表される最後の実行の期間。
  19. [Max_Duration]:ジョブの実行にかかった最大期間(時間:分:秒の形式)。
  20. [Next_Run]:ジョブが次回実行される日時。この情報は、スケジュールされているジョブでのみ使用できます(スケジュールはジョブに関連付けられています)。
  21. [JobDeletionCriterion]:ジョブを削除するための基準。 SQL Serverエージェントには、特定の基準に基づいてジョブを削除/削除できる機能があるため、ジョブを手動で削除/クリーンアップする必要はありません。
  22. [OriginatingServerName]:ジョブの実行元のサーバー。
  23. [サブシステム]:SQL Server Integration Servicesパッケージ、Transact-SQLスクリプト(T-SQL)、ActiveXスクリプトなどのジョブステップのタイプ。
  24. [コマンド]:サブシステムによって実行される実際のコマンド。
  25. [メッセージ]:ジョブの成功/失敗などに関する情報。
5
Kundan Dasange