【问题标题】:Get date of last successful job run?获取上次成功运行作业的日期?
【发布时间】:2010-01-21 20:57:00
【问题描述】:

我有一个执行存储过程的单步作业。我想获取最后一次成功执行作业的日期,这样我就可以更新一个增量而不是整个数据集。

现在我的作业设置每天运行一次,所以我有一个默认参数,如果它为 null,我将其设置为 GETDATE() - 1,所以我仍在更新增量,但我想要do 将日期设置为最后一次成功执行作业。

exec dbo.usp_UpdateFrom @LastSuccessfulExecutionTime

当前程序类似于

CREATE PROCEDURE dbo.usp_UpdateFrom
    @FromDate datetime = NULL --would like to pass last successful execution time of the job
AS
    IF @FromDate IS NULL
        SET @FromDate = GETDATE() - 1

    -- do stuff
END

【问题讨论】:

    标签: sql-server sql-server-agent


    【解决方案1】:

    您想要的表是msdb 中的sysjobssysjobhistory。虽然被警告! SQL Server 只维护一定数量的记录,所以如果作业太多且历史记录不够大,最终会导致没有历史记录。

    以下代码检索给定作业名称的job_id,并查询历史表以查找最后一次成功完成的运行(即步骤 0,状态 1)。如您所见,您必须将运行时间转换回日期,因为 SQL Server 将其存储在两个 int 列中:

    DECLARE @job_id binary(16)
    SELECT @job_id = job_id FROM msdb.dbo.sysjobs WHERE (name = N'YourJobName')
    
    SELECT TOP 1
        CONVERT(DATETIME, RTRIM(run_date))
        + ((run_time / 10000 * 3600) 
        + ((run_time % 10000) / 100 * 60) 
        + (run_time % 10000) % 100) / (86399.9964) AS run_datetime
        , *
    FROM
        msdb..sysjobhistory sjh
    WHERE
        sjh.step_id = 0 
        AND sjh.run_status = 1 
        AND sjh.job_id = @job_id
    ORDER BY
        run_datetime DESC
    

    【讨论】:

    • 感谢您提供有关 sysjobhistory 的信息,但恐怕要依赖于工作名称。
    • 认为这对您来说可能更容易。没有职位名称就更简单了!
    • 是的,但我仍然需要获取 job_id
    • 嗯..您可以通过查看 msdb..sysjobs 并在脚本中对其进行硬编码来手动获取它?除非您将其删除,否则 job_id 不会更改。如果您不知道 job_id 是什么并且它可以更改,请坚持使用 jobname
    • 我提供的答案演示了如何在不依赖作业名称的情况下获取 job_id。
    【解决方案2】:

    由于sysjobhistory 只维护一定数量的记录,我推荐使用sysjobactivity,它保留了每个作业和会话的最后执行“历史”。

    SELECT TOP 1 start_execution_date
    FROM msdb.dbo.sysjobactivity
    WHERE run_requested_date IS NOT NULL
    AND job_id = @job_id
    ORDER BY session_id DESC;
    

    注意:如果一个作业在会话的生命周期内没有被执行,几乎所有的值都是null

    ALSO 有一个系统存储过程 sp_help_job 返回此信息。 它接受job_idenabled等作为参数返回1条或多条记录。

    【讨论】:

      【解决方案3】:

      看看this 文章,它可能会为您指明正确的方向。不幸的是,我的家用计算机上没有 SQL Server,因此无法为您进行测试!

      您基本上需要查询 sysjobactivity 表并从 start_execution_date 和 stop_execution_date 中获取值。你需要 job_id,但我不确定你从哪里得到它。

      我希望这会有所帮助。

      编辑 好的,我又做了一些研究,发现下面的代码sn-p

      DECLARE @jobId binary(16)
      
      SELECT @jobId = job_id FROM msdb.dbo.sysjobs WHERE (name = N'Name of Your Job')
      

      【讨论】:

        【解决方案4】:

        要获得上次成功运行的作业:

        SELECT 
            h.[job_id]
            ,j.Name JobName
            ,CONVERT(CHAR(10), CAST(STR(run_date,8, 0) AS dateTIME), 111)   [LastRunDate]
           ,STUFF(STUFF(RIGHT('000000' + 
            CAST (run_time AS`` VARCHAR(6 ) ) ,6),5,0,':'),3,0,':') [LastRunTime]
           ,CASE run_status 
            WHEN 0 THEN 'Failed' 
            WHEN 1 THEN 'Succeeded' 
            WHEN 2 THEN 'Retry' 
            WHEN 3 THEN 'Cancelled' 
            WHEN 4 THEN 'In Progress' 
            END AS ExecutionStatus                                                 
            FROM [msdb].[dbo].[sysjobhistory] h 
            JOIN msdb.dbo.sysjobs j ON h.job_id=j.job_id 
            WHERE run_status=1 
            ORDER BY run_date DESC,run_time DESC
        

        【讨论】:

          【解决方案5】:

          使用来自以下线程的信息:

          http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=112427 http://www.sqlservercentral.com/Forums/Topic542581-145-1.aspx

          这就是我想出的......

          DECLARE 
              @statement nvarchar(72),
              @job_id uniqueidentifier,
              @last_run_date datetime
          
          SET @statement = 'SET @guid = CAST(' + SUBSTRING(APP_NAME(), 30, 34) + ' as uniqueidentifier)'
          
          EXECUTE sp_executesql @statement, N'@guid uniqueidentifier OUT', @guid = @job_id OUT
          
          SELECT TOP (1)
              @last_run_date = CAST(STR(run_date, 8, 0) as datetime) + CAST(STUFF(STUFF(STR(run_time, 6, 0), 3, 0, ':'), 6, 0, ':') as datetime)
          FROM msdb.dbo.sysjobhistory 
          WHERE job_id = @job_id
          AND run_status = 1
          ORDER BY
              CAST(STR(run_date, 8, 0) as datetime) + CAST(STUFF(STUFF(STR(run_time, 6, 0), 3, 0, ':'), 6, 0, ':') as datetime) DESC
          
          EXEC dbo.usp_UpdateFrom @last_run_date
          

          我对此不是特别满意,但我更喜欢这种根据作业名称获取 job_id 的方法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多