DFo*_*k42 5 sql-server-2005 sql-server
我正在尝试为报告创建一个视图,以便我可以轻松跟踪我在服务器上安排的所有备份。所有这些备份都安排在维护计划的子计划中,因此作业名称都以“Backup.”开头。
我遇到的问题是,我希望能够轻松查看作业计划再次运行的时间以及计划的频率。sysschedules 表具有字段 freq_type 和 freq_interval。可以在此处找到它们的值的定义。正如您所看到的,由于缺乏更好的描述方式,这些字段是累积的。我不知道如何在基于集合的解决方案中进行设置,以便我可以看到当天的名称。
我希望能够看到诸如“每 3 天执行一次”或“每周一、二、五执行”之类的内容。
我怎样才能写这个,这样我就不会使用多层 case 语句来得到我想要的东西?
到目前为止,这是我的代码:
select
j.job_id,
j.name,
s.next_run_date,
s.next_run_time,
ss.*
from msdb.dbo.sysjobs j
left outer join msdb.dbo.sysjobschedules s
on j.job_id=s.job_id
left outer join msdb.dbo.sysschedules ss
on s.schedule_id=ss.schedule_id
where j.name like 'backup.%'
Run Code Online (Sandbox Code Playgroud)
小智 6
如果您想要 SQL Server 使用的所有整数值的纯英文版本(至少就我对 T-SQL 的有限了解而言),除了使用 case 语句之外别无他法。这是很多 DBA 都需要的常见事情,并且有很多关于该主题的脚本。我发现下面来自 Michelle Ufford 的脚本对于很好地了解正在运行的作业时间表非常有用。由于维护计划最终会作为 SQL 代理作业,这也将向您展示这一点。
您从脚本中获得的输出将为您提供频率、子频率、预定时间以及下次运行时间和日期。我只是把她的脚本作为一个存储过程放在我的服务器上,这样我就可以在需要时轻松地运行它。如果你愿意,你也可以把它作为一个视图。由于其他人可以在我身后添加工作等,因此我喜欢时不时地检查一下,看看发生了什么。
/*
Description: SQL Agent Information
Source: SQLFool, http://sqlfool.com/2012/09/sql-agent-job-script-2/
*/
SET NOCOUNT ON;
DECLARE @jobHistory TABLE (
job_id UNIQUEIDENTIFIER
,success INT
,cancel INT
,fail INT
,retry INT
,last_run_status CHAR(12)
,last_execution_id INT
,last_duration CHAR(8)
,last_execution_start DATETIME
);
WITH lastExecution
AS (
SELECT job_id
,MAX(instance_id) AS last_instance_id
FROM msdb.dbo.sysjobhistory
WHERE step_id = 0
GROUP BY job_id
)
INSERT INTO @jobHistory
SELECT sjh.job_id
,SUM(CASE
WHEN sjh.run_status = 1
AND step_id = 0
THEN 1
ELSE 0
END) AS success
,SUM(CASE
WHEN sjh.run_status = 3
AND step_id = 0
THEN 1
ELSE 0
END) AS cancel
,SUM(CASE
WHEN sjh.run_status = 0
AND step_id = 0
THEN 1
ELSE 0
END) AS fail
,SUM(CASE
WHEN sjh.run_status = 2
THEN 1
ELSE 0
END) AS retry
,CASE sjh.run_status
WHEN 0
THEN 'Failed'
WHEN 1
THEN 'Succeeded'
WHEN 2
THEN 'Retry'
WHEN 3
THEN 'Canceled'
WHEN 4
THEN 'In Progress'
ELSE 'Unknown'
END AS last_run_status
,MAX(CASE
WHEN sjh.step_id = 0
THEN instance_id
ELSE NULL
END) last_execution_id
,SUBSTRING(CAST(MAX(CASE
WHEN le.job_id IS NOT NULL
THEN sjh.run_duration
ELSE NULL
END) + 1000000 AS VARCHAR(7)), 2, 2) + ':' + SUBSTRING(CAST(MAX(CASE
WHEN le.job_id IS NOT NULL
THEN sjh.run_duration
ELSE NULL
END) + 1000000 AS VARCHAR(7)), 4, 2) + ':' + SUBSTRING(CAST(MAX(CASE
WHEN le.job_id IS NOT NULL
THEN sjh.run_duration
ELSE NULL
END) + 1000000 AS VARCHAR(7)), 6, 2) AS last_duration
,MAX(CASE
WHEN le.last_instance_id IS NOT NULL
THEN CONVERT(DATETIME, RTRIM(run_date)) + ((run_time / 10000 * 31200) + ((run_time % 10000) / 100 * 60) + (run_time % 10000) % 100) / (86399.9964)
ELSE '1900-01-01'
END) AS last_execution_start
FROM msdb.dbo.sysjobhistory AS sjh
LEFT JOIN lastExecution AS le ON sjh.job_id = le.job_id
AND sjh.instance_id = le.last_instance_id
GROUP BY sjh.job_id
,sjh.run_status;
/* We need to parse the schedule into something we can understand */
DECLARE @weekDay TABLE (
mask INT
,maskValue VARCHAR(32)
);
INSERT INTO @weekDay
SELECT 1
,'Sunday'
UNION ALL
SELECT 2
,'Monday'
UNION ALL
SELECT 4
,'Tuesday'
UNION ALL
SELECT 8
,'Wednesday'
UNION ALL
SELECT 16
,'Thursday'
UNION ALL
SELECT 32
,'Friday'
UNION ALL
SELECT 64
,'Saturday';
/* Now let's get our schedule information */
WITH myCTE
AS (
SELECT sched.name AS 'scheduleName'
,sched.schedule_id
,jobsched.job_id
,CASE
WHEN sched.freq_type = 1
THEN 'Once'
WHEN sched.freq_type = 4
AND sched.freq_interval = 1
THEN 'Daily'
WHEN sched.freq_type = 4
THEN 'Every ' + CAST(sched.freq_interval AS VARCHAR(5)) + ' days'
WHEN sched.freq_type = 8
THEN REPLACE(REPLACE(REPLACE((
SELECT maskValue
FROM @weekDay AS x
WHERE sched.freq_interval & x.mask <> 0
ORDER BY mask
FOR XML RAW
), '"/><row maskValue="', ', '), '<row maskValue="', ''), '"/>', '') + CASE
WHEN sched.freq_recurrence_factor <> 0
AND sched.freq_recurrence_factor = 1
THEN '; weekly'
WHEN sched.freq_recurrence_factor <> 0
THEN '; every ' + CAST(sched.freq_recurrence_factor AS VARCHAR(10)) + ' weeks'
END
WHEN sched.freq_type = 16
THEN 'On day ' + CAST(sched.freq_interval AS VARCHAR(10)) + ' of every ' + CAST(sched.freq_recurrence_factor AS VARCHAR(10)) + ' months'
WHEN sched.freq_type = 32
THEN CASE
WHEN sched.freq_relative_interval = 1
THEN 'First'
WHEN sched.freq_relative_interval = 2
THEN 'Second'
WHEN sched.freq_relative_interval = 4
THEN 'Third'
WHEN sched.freq_relative_interval = 8
THEN 'Fourth'
WHEN sched.freq_relative_interval = 16
THEN 'Last'
END + CASE
WHEN sched.freq_interval = 1
THEN ' Sunday'
WHEN sched.freq_interval = 2
THEN ' Monday'
WHEN sched.freq_interval = 3
THEN ' Tuesday'
WHEN sched.freq_interval = 4
THEN ' Wednesday'
WHEN sched.freq_interval = 5
THEN ' Thursday'
WHEN sched.freq_interval = 6
THEN ' Friday'
WHEN sched.freq_interval = 7
THEN ' Saturday'
WHEN sched.freq_interval = 8
THEN ' Day'
WHEN sched.freq_interval = 9
THEN ' Weekday'
WHEN sched.freq_interval = 10
THEN ' Weekend'
END + CASE
WHEN sched.freq_recurrence_factor <> 0
AND sched.freq_recurrence_factor = 1
THEN '; monthly'
WHEN sched.freq_recurrence_factor <> 0
THEN '; every ' + CAST(sched.freq_recurrence_factor AS VARCHAR(10)) + ' months'
END
WHEN sched.freq_type = 64
THEN 'StartUp'
WHEN sched.freq_type = 128
THEN 'Idle'
END AS 'frequency'
,ISNULL('Every ' + CAST(sched.freq_subday_interval AS VARCHAR(10)) + CASE
WHEN sched.freq_subday_type = 2
THEN ' seconds'
WHEN sched.freq_subday_type = 4
THEN ' minutes'
WHEN sched.freq_subday_type = 8
THEN ' hours'
END, 'Once') AS 'subFrequency'
,REPLICATE('0', 6 - LEN(sched.active_start_time)) + CAST(sched.active_start_time AS VARCHAR(6)) AS 'startTime'
,REPLICATE('0', 6 - LEN(sched.active_end_time)) + CAST(sched.active_end_time AS VARCHAR(6)) AS 'endTime'
,REPLICATE('0', 6 - LEN(jobsched.next_run_time)) + CAST(jobsched.next_run_time AS VARCHAR(6)) AS 'nextRunTime'
,CAST(jobsched.next_run_date AS CHAR(8)) AS 'nextRunDate'
FROM msdb.dbo.sysschedules AS sched
INNER JOIN msdb.dbo.sysjobschedules AS jobsched ON sched.schedule_id = jobsched.schedule_id
WHERE sched.enabled = 1
)
/* Finally, let's look at our actual jobs and tie it all together */
SELECT job.name AS [jobName]
,l.name AS [jobOwner]
,CASE
WHEN job.enabled = 1
THEN 'Enabled'
ELSE 'Disabled'
END AS [jobStatus]
,COALESCE(sched.scheduleName, '(unscheduled)') AS [scheduleName]
,COALESCE(sched.frequency, '') AS [frequency]
,COALESCE(sched.subFrequency, '') AS [subFrequency]
,COALESCE(SUBSTRING(sched.startTime, 1, 2) + ':' + SUBSTRING(sched.startTime, 3, 2) + ' - ' + SUBSTRING(sched.endTime, 1, 2) + ':' + SUBSTRING(sched.endTime, 3, 2), '') AS [scheduleTime] -- HH:MM
,COALESCE(SUBSTRING(sched.nextRunDate, 1, 4) + '/' + SUBSTRING(sched.nextRunDate, 5, 2) + '/' + SUBSTRING(sched.nextRunDate, 7, 2) + ' ' + SUBSTRING(sched.nextRunTime, 1, 2) + ':' + SUBSTRING(sched.nextRunTime, 3, 2), '') AS [nextRunDate]
/* Note: the sysjobschedules table refreshes every 20 min, so nextRunDate may be out of date */
,COALESCE(jh.success, 0) AS [success]
,COALESCE(jh.cancel, 0) AS [cancel]
,COALESCE(jh.fail, 0) AS [fail]
,COALESCE(jh.retry, 0) AS [retry]
,jh.last_run_status AS [lastRunStatus]
,CASE job.notify_level_email
WHEN 0
THEN 'None'
WHEN 1
THEN 'Succeeds'
WHEN 2
THEN 'Fails'
WHEN 3
THEN 'Completion'
ELSE 'Unknown'
END AS [EmailNotification]
,CASE job.notify_level_eventlog
WHEN 0
THEN 'None'
WHEN 1
THEN 'Succeeds'
WHEN 2
THEN 'Fails'
WHEN 3
THEN 'Completion'
ELSE 'Unknown'
END AS [EventLogNotification]
FROM msdb.dbo.sysjobs AS job
INNER JOIN master.sys.syslogins l ON l.sid = job.owner_sid
LEFT JOIN myCTE AS sched ON job.job_id = sched.job_id
LEFT JOIN @jobHistory AS jh ON job.job_id = jh.job_id
LEFT JOIN msdb.dbo.sysoperators oper ON job.notify_email_operator_id = oper.id
WHERE job.enabled = 1 -- do not display disabled jobs
AND jh.last_execution_start > '1900-01-01'
ORDER BY jobName
OPTION (RECOMPILE);
GO
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5285 次 |
| 最近记录: |