Przy administracji zadaniami, które uruchamia SQL Agent oraz przygotowywaniu przemyślanego harmonogramu, chcemy uniknąć niepotrzebnych incydentów, tak by wszystko działało sprawnie. Uważając by zadania nie nachodziły na siebie i tym samym nie doszło do blokowania odczytu do obiektów bazodanowych, bądź nagłego skoku zużycia dostępnych zasobów. Do tego potrzebujemy listy zadań i godzin w których są wykonywane, przeglądanie każdego zadania i sprawdzanie kiedy jest uruchamiany może się jeszcze sprawdzać przy małej ilości zadań, np. 5 czy 10. W momencie kiedy mamy do czynienia z dobrze rozbudowanym systemem integracyjnym czy zadaniami administracyjnymi to tych zadań mogą być setki – a przechodzenie po każdym z nich mija się z efektywnością.
Przejdźmy do szczegółów, a mianowicie do tabel, gdzie przechowywane są interesujące nas dane. Całość umieszczona jest w bazie msdb, przeglądając zawartość odnajdziemy takie tabele jak [sysjobs] (zawiera listę zadań) czy [sysjobsteps] (zawiera kroki zawarte w zadaniu). Tabele te będą stanowić bazę do naszego zapytania.

Jak widzimy na powyższym zrzucie w tabeli [sysjobs] znajdziemy informacje takie jak nazwa, status włączenia, opis czy krok od którego rozpoczyna się zadanie.

W tabeli [sysjobsteps] widzimy już szczegóły każdego kroku, w tym chociażby samo polecenie jakie ma wykonać.
Do naszego zapytania dodajmy jeszcze pozostałe tabele, które dostarczą nam więcej informacji. Odpowiednia modyfikacja kwerendy i przed naszymi oczami pojawiają się już kolejne pola np. data kolejnego uruchomienia, ostatnia godzina wykonania w ciągu dnia czy opisy jaki rodzaj harmonogramu został ustalony.

Ostateczny kod prezentuje się następująco:
SELECT
job.job_id
, steps.database_name
, job.name AS job_name
, job.enabled
, steps.step_name
, steps.command
, job.notify_level_email
, job.description
, schedule_info.schedule_id
, schedule_info.name AS schedule_name
, CONCAT(schedule_info.active_end_time / 10000, ':', RIGHT(schedule_info.active_end_time / 100, 2), ':', RIGHT(schedule_info.active_end_time, 2)) AS last_run_hour
, CONVERT(DATETIME, CONCAT(scheduler.next_run_date, ' ', scheduler.next_run_time / 10000, ':', RIGHT(scheduler.next_run_time / 100, 2), ':', RIGHT(scheduler.next_run_time, 2))) AS next_run
, CASE WHEN schedule_info.freq_type = 1 THEN 'once' WHEN schedule_info.freq_type = 4 THEN 'daily' WHEN schedule_info.freq_type = 8 THEN 'weekly' WHEN schedule_info.freq_type = 16 THEN 'monthly'
WHEN schedule_info.freq_type = 32 THEN 'monthly relative' WHEN schedule_info.freq_type = 64 THEN 'Agent start' WHEN schedule_info.freq_type = 128 THEN 'computer idle' END AS freq_type
, schedule_info.freq_subday_interval
, CASE WHEN schedule_info.freq_subday_type = 1 THEN 'specified time' WHEN schedule_info.freq_subday_type = 2 THEN 'seconds' WHEN schedule_info.freq_subday_type = 4 THEN 'minutes'
WHEN schedule_info.freq_subday_type = 8 THEN 'hours' END AS freq_subday_time
FROM
msdb.dbo.sysjobs job
INNER JOIN
msdb.dbo.sysjobsteps steps
ON
job.job_id = steps.job_id
INNER JOIN
msdb.dbo.sysjobschedules scheduler
ON
job.job_id = scheduler.job_id
LEFT JOIN
msdb.dbo.sysschedules schedule_info
ON
scheduler.schedule_id = schedule_info.schedule_id
WHERE
job.enabled = 1
ORDER BY
job.name