Preskočiť na obsah
Skript

SQL Agent joby – harmonogram, vlastník, notifikácie

Všetky joby s čitateľným harmonogramom („týždenne: po, pi o 02:00:00“), najbližším spustením, vlastníkom, notifikáciou operátora pri zlyhaní a výsledkom posledného behu.

sql-agent-joby-harmonogram-vlastnik-notifikacie.sql 85 riadkov · T-SQL
Parametre skriptu doplň a kopíruj hotový skript
/* DeadlockCafe | SQL Agent joby – harmonogram, vlastník, notifikácie
   Účel:  Všetky joby s čitateľným harmonogramom („týždenne: po, pi o 02:00:00“), najbližším spustením, vlastníkom, notifikáciou operátora pri zlyhaní a výsledkom posledného behu.
   Režim: READ ONLY | SQL Server 2016 – 2022, on-premises
*/
SET NOCOUNT ON;

;WITH last_run AS
(
    SELECT h.job_id, h.run_status, h.run_date, h.run_time,
           ROW_NUMBER() OVER (PARTITION BY h.job_id ORDER BY h.instance_id DESC) AS rn
    FROM msdb.dbo.sysjobhistory AS h
    WHERE h.step_id = 0
)
SELECT j.name                    AS job_name,
       j.enabled                 AS job_enabled,
       cat.name                  AS category,
       SUSER_SNAME(j.owner_sid)  AS job_owner,
       s.name                    AS schedule_name,
       s.enabled                 AS schedule_enabled,
       CASE WHEN s.schedule_id IS NULL THEN N'(bez harmonogramu)' ELSE
           CASE s.freq_type
                WHEN 1   THEN N'jednorazovo ' + ISNULL(CONVERT(char(10), TRY_CONVERT(date, CONVERT(char(8), s.active_start_date), 112), 120), N'')
                WHEN 4   THEN CASE WHEN s.freq_interval = 1 THEN N'denne'
                                   ELSE N'každý ' + CONVERT(nvarchar(10), s.freq_interval) + N'. deň' END
                WHEN 8   THEN CASE WHEN s.freq_recurrence_factor > 1
                                   THEN N'každý ' + CONVERT(nvarchar(10), s.freq_recurrence_factor) + N'. týždeň: '
                                   ELSE N'týždenne: ' END
                              + ISNULL(STUFF(  CASE WHEN (s.freq_interval & 2)  = 2  THEN N', po' ELSE N'' END
                                             + CASE WHEN (s.freq_interval & 4)  = 4  THEN N', ut' ELSE N'' END
                                             + CASE WHEN (s.freq_interval & 8)  = 8  THEN N', st' ELSE N'' END
                                             + CASE WHEN (s.freq_interval & 16) = 16 THEN N', št' ELSE N'' END
                                             + CASE WHEN (s.freq_interval & 32) = 32 THEN N', pi' ELSE N'' END
                                             + CASE WHEN (s.freq_interval & 64) = 64 THEN N', so' ELSE N'' END
                                             + CASE WHEN (s.freq_interval & 1)  = 1  THEN N', ne' ELSE N'' END, 1, 2, N''), N'?')
                WHEN 16  THEN N'mesačne, ' + CONVERT(nvarchar(10), s.freq_interval) + N'. deň'
                              + CASE WHEN s.freq_recurrence_factor > 1
                                     THEN N' (každý ' + CONVERT(nvarchar(10), s.freq_recurrence_factor) + N'. mesiac)' ELSE N'' END
                WHEN 32  THEN N'mesačne, '
                              + CASE s.freq_relative_interval WHEN 1 THEN N'prvý' WHEN 2 THEN N'druhý' WHEN 4 THEN N'tretí'
                                     WHEN 8 THEN N'štvrtý' WHEN 16 THEN N'posledný' ELSE N'?' END + N' '
                              + CASE s.freq_interval WHEN 1 THEN N'nedeľa' WHEN 2 THEN N'pondelok' WHEN 3 THEN N'utorok'
                                     WHEN 4 THEN N'streda' WHEN 5 THEN N'štvrtok' WHEN 6 THEN N'piatok' WHEN 7 THEN N'sobota'
                                     WHEN 8 THEN N'deň' WHEN 9 THEN N'pracovný deň' WHEN 10 THEN N'víkendový deň' ELSE N'?' END
                              + CASE WHEN s.freq_recurrence_factor > 1
                                     THEN N' (každý ' + CONVERT(nvarchar(10), s.freq_recurrence_factor) + N'. mesiac)' ELSE N'' END
                WHEN 64  THEN N'pri štarte SQL Agenta'
                WHEN 128 THEN N'keď je počítač nečinný'
                ELSE N'neznámy freq_type ' + CONVERT(nvarchar(10), s.freq_type)
           END
           + CASE WHEN s.freq_type IN (1, 4, 8, 16, 32) THEN
                  CASE s.freq_subday_type
                       WHEN 1 THEN N' o ' + st.t
                       WHEN 2 THEN N', každých ' + CONVERT(nvarchar(10), s.freq_subday_interval) + N' s (' + st.t + N' – ' + et.t + N')'
                       WHEN 4 THEN N', každých ' + CONVERT(nvarchar(10), s.freq_subday_interval) + N' min (' + st.t + N' – ' + et.t + N')'
                       WHEN 8 THEN N', každých ' + CONVERT(nvarchar(10), s.freq_subday_interval) + N' h (' + st.t + N' – ' + et.t + N')'
                       ELSE N'' END
             ELSE N'' END
       END                       AS schedule_text,
       CASE WHEN js.next_run_date > 0
            THEN DATEADD(SECOND, js.next_run_time / 10000 * 3600 + js.next_run_time / 100 % 100 * 60 + js.next_run_time % 100,
                         CONVERT(datetime, CONVERT(char(8), js.next_run_date), 112)) END AS next_run,
       CASE j.notify_level_email WHEN 0 THEN N'nikdy' WHEN 1 THEN N'pri úspechu'
            WHEN 2 THEN N'pri zlyhaní' WHEN 3 THEN N'vždy' END                      AS email_when,
       op.name                   AS email_operator,
       CASE WHEN j.notify_level_email IN (2, 3) AND op.name IS NOT NULL THEN N'OK'
            ELSE N'CHÝBA' END    AS failure_notification,
       CASE WHEN sp.principal_id IS NULL THEN N'vlastník nemá login (SID ' + CONVERT(nvarchar(200), j.owner_sid, 1) + N')'
            WHEN sp.is_disabled = 1 THEN N'vlastník je vypnutý login'
            ELSE N'' END         AS owner_note,
       CASE lr.run_status WHEN 0 THEN N'FAILED' WHEN 1 THEN N'SUCCEEDED' WHEN 2 THEN N'RETRY'
            WHEN 3 THEN N'CANCELED' WHEN 4 THEN N'IN PROGRESS' END                  AS last_run_status,
       CASE WHEN lr.run_date > 0
            THEN DATEADD(SECOND, lr.run_time / 10000 * 3600 + lr.run_time / 100 % 100 * 60 + lr.run_time % 100,
                         CONVERT(datetime, CONVERT(char(8), lr.run_date), 112)) END AS last_run_at
FROM msdb.dbo.sysjobs AS j
LEFT JOIN msdb.dbo.syscategories   AS cat ON cat.category_id = j.category_id
LEFT JOIN msdb.dbo.sysjobschedules AS js  ON js.job_id = j.job_id
LEFT JOIN msdb.dbo.sysschedules    AS s   ON s.schedule_id = js.schedule_id
LEFT JOIN msdb.dbo.sysoperators    AS op  ON op.id = j.notify_email_operator_id
LEFT JOIN sys.server_principals    AS sp  ON sp.sid = j.owner_sid
LEFT JOIN last_run                 AS lr  ON lr.job_id = j.job_id AND lr.rn = 1
OUTER APPLY (SELECT STUFF(STUFF(RIGHT('000000' + CONVERT(varchar(6), s.active_start_time), 6), 5, 0, ':'), 3, 0, ':') AS t) AS st
OUTER APPLY (SELECT STUFF(STUFF(RIGHT('000000' + CONVERT(varchar(6), s.active_end_time), 6), 5, 0, ':'), 3, 0, ':') AS t) AS et
ORDER BY j.name, s.name;
## Kedy použiť

Pri prevzatí servera, pred migráciou (čo všetko treba preniesť), pri hľadaní kolízií údržby alebo keď sa pýtaš, prečo nikto nedostal e-mail o zlyhanom jobe.

## Ako čítať výsledok

Jeden riadok = job × harmonogram (job s dvoma harmonogramami má dva riadky, job bez harmonogramu má „(bez harmonogramu)“). `job_enabled` / `schedule_enabled` = 0 znamená, že sa nespustí. `failure_notification` = CHÝBA → pri zlyhaní nikto nedostane e-mail. `owner_note` upozorní na vlastníka bez loginu alebo s vypnutým loginom – job potom zlyhá pri ďalšom behu.

> [!WARNING]
> `next_run` pochádza z `sysjobschedules`, ktorú Agent obnovuje približne každých 20 minút – môže byť mierne neaktuálny. História behov sa čistí podľa nastavení Agenta. Notifikácia cez e-mail funguje len so zapnutým Database Mail a profilom v nastaveniach Agenta – to skript nekontroluje.

**Oprávnenia:** Čítanie agent tabuliek v msdb, napr. rola `SQLAgentReaderRole` (alebo `sysadmin` pre všetky joby).  
**Režim:** READ ONLY · **Verzia:** SQL Server 2016 – 2022

## Súvisiace recepty

- [SQL Agent – joby, ktoré naposledy zlyhali](script.php?id=40&s=sql-agent-joby-ktore-naposledy-zlyhali)
- [SQL Agent – práve bežiace joby](script.php?id=41&s=sql-agent-prave-beziace-joby)
- [Migrácia databázy na nový server – checklist](script.php?id=62&s=migracia-databazy-na-novy-server-checklist)

## Zdroje

- [dbo.sysjobs](https://learn.microsoft.com/en-us/sql/relational-databases/system-tables/dbo-sysjobs-transact-sql)
- [dbo.sysschedules](https://learn.microsoft.com/en-us/sql/relational-databases/system-tables/dbo-sysschedules-transact-sql)
- [dbo.sysjobschedules](https://learn.microsoft.com/en-us/sql/relational-databases/system-tables/dbo-sysjobschedules-transact-sql)
- [dbo.sysjobhistory](https://learn.microsoft.com/en-us/sql/relational-databases/system-tables/dbo-sysjobhistory-transact-sql)

_Skript je staticky overený proti dokumentácii Microsoft Learn (názvy DMV, stĺpcov a hodnôt), nie spustený na živom serveri. Pred použitím na PROD ho vyskúšaj na TEST._