Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
Rhahn
Starting Member
9 Posts |
Posted - 2005-12-20 : 12:51:13
|
I have a number of jobs that run on my production server. This last weekend I had to disable all jobs (msdb.dbo.sys_jobs.enabled = 0) for maintenance reasons. On Monday I ran a script that set all the enabled = 0 to enabled = 1. In Enterprise manager the next run times where correct and I manually started, or set the next run date, on any jobs that should have run during the time they where disabled. Tuesday I look and there are jobs that should have run Tuesday morning but have not. Does any one know why the timers get all screwed up when you disable a job and more importantly does any one know of a Quick way to reinsulated all the timers without manually going through each one and resetting the start date? |
|
SQLServerDBA_Dan
Aged Yak Warrior
752 Posts |
Posted - 2005-12-20 : 13:27:56
|
quote: Originally posted by Rhahn Does any one know why the timers get all screwed up when you disable a job and more importantly does any one know of a Quick way to reinsulated all the timers without manually going through each one and resetting the start date?
You'll need to run the system proc: xp_sqlagent_notifyThe SQL Server Agent keeps the job data cached. You can't just update system tables and do nothing else and still think that things will work correctly. Here's some code to run it:DECLARE @JOBNAME varchar(150)SET @JOBNAME = 'INSERT JOB NAME HERE'UPDATE msdb..sysjobschedules SET Enabled = 1 --, active_start_date = convert(varchar(8), getdate(), 112), active_start_time = left(replace(convert(varchar(8), dateadd(n, 1, getdate()), 8), ':', ''), 4) + '00', next_run_date = convert(varchar(8), getdate(), 112), next_run_time = left(replace(convert(varchar(8), dateadd(n, 1, getdate()), 8), ':', ''), 4) + '00'FROM msdb..sysjobs j LEFT OUTER JOIN msdb..sysjobschedules s ON (s.job_id = j.job_id)WHERE j.Name = @JOBNAMEDECLARE @job_id UNIQUEIDENTIFIER, @schedule_id intSELECT @job_id = j.Job_ID, @schedule_id = S.Schedule_ID FROM msdb..sysjobs j (NoLock) LEFT OUTER JOIN msdb..sysjobschedules s (NoLock) ON (s.job_id = j.job_id) WHERE j.Name = @JOBNAME-- Update the job's version/last-modified information UPDATE msdb.dbo.sysjobs SET version_number = version_number + 1, date_modified = GETDATE() WHERE (job_id = @job_id) -- Notify SQLServerAgent of the change, but only if we know the job has been cached IF (EXISTS ( SELECT s.* FROM msdb.dbo.sysjobservers s (NoLock) INNER JOIN msdb.dbo.sysjobs j (NoLock) on (j.job_id = s.job_id) WHERE server_id = 0 and j.name = @JOBNAME) ) BEGIN EXEC master.dbo.xp_sqlagent_notify 'S', @job_id, @schedule_id, null, 'U', 'INSERT NT ACCOUNT HERE', 1, @@trancount END GO Have fun,Daniel, MCP, A+SQL Server DBAwww.dallasteam.com |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2005-12-20 : 13:31:56
|
That's what happens when you modify system tables directly. To update jobs, you can use the system stored procedures or via the GUI in EM.Tara Kizeraka tduggan |
|
|
Rhahn
Starting Member
9 Posts |
Posted - 2005-12-20 : 13:49:43
|
So it’s a bad idea to modify systables, check. Using EM is way to slow and my fingers get soar from repetitive clicking. How would one do this: Update sysjobs Set enabled = 0 Where category_id = 3Using system_sp’s? |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2005-12-20 : 13:52:40
|
Here is a sample of how to disable all jobs. The code is from my toolbox and looking at it now, it can be simplified a bit, but it should give you an idea of how to do things. SET NOCOUNT ONCREATE TABLE #Job_Names( Job_Name SYSNAME NOT NULL)INSERT INTO #Job_NamesSELECT nameFROM msdb.dbo.sysjobsORDER BY nameDECLARE @job_name SYSNAMEDECLARE @job_id UNIQUEIDENTIFIERDECLARE disable_jobs CURSOR FOR SELECT Job_NameFROM #Job_NamesSET @job_id = NULLOPEN disable_jobsFETCH NEXT FROM disable_jobs INTO @job_nameWHILE @@FETCH_STATUS = 0BEGIN EXEC msdb.dbo.sp_verify_job_identifiers '@job_name', '@job_id', @job_name OUTPUT, @job_id OUTPUT EXEC msdb.dbo.sp_update_job @job_id, @enabled = 0 SET @job_id = NULL FETCH NEXT FROM disable_jobs INTO @job_nameENDCLOSE disable_jobsDEALLOCATE disable_jobsDROP TABLE #Job_Names There is a category_name parameter to sp_update_job, so perhaps that can be used to satisfy your request. Or you can modify the select into the temp table in my code to grab the jobs that you want and then use the rest of the code.Tara Kizeraka tduggan |
|
|
SQLServerDBA_Dan
Aged Yak Warrior
752 Posts |
Posted - 2005-12-20 : 13:55:28
|
quote: Originally posted by Rhahn So it’s a bad idea to modify systables, check. Using EM is way to slow and my fingers get soar from repetitive clicking. How would one do this: Update sysjobs Set enabled = 0 Where category_id = 3Using system_sp’s?
Grrr...quote: Originally posted by Rhahn You'll need to run the system proc: xp_sqlagent_notifyThe SQL Server Agent keeps the job data cached. You can't just update system tables and do nothing else and still think that things will work correctly.
Daniel, MCP, A+SQL Server DBAwww.dallasteam.com |
|
|
SQLServerDBA_Dan
Aged Yak Warrior
752 Posts |
Posted - 2005-12-20 : 13:59:30
|
quote: Originally posted by tkizer Here is a sample of how to disable all jobs. The code is from my toolbox and looking at it now, it can be simplified a bit, but it should give you an idea of how to do things. SET NOCOUNT ONCREATE TABLE #Job_Names( Job_Name SYSNAME NOT NULL)INSERT INTO #Job_NamesSELECT nameFROM msdb.dbo.sysjobsORDER BY nameDECLARE @job_name SYSNAMEDECLARE @job_id UNIQUEIDENTIFIERDECLARE disable_jobs CURSOR FOR SELECT Job_NameFROM #Job_NamesSET @job_id = NULLOPEN disable_jobsFETCH NEXT FROM disable_jobs INTO @job_nameWHILE @@FETCH_STATUS = 0BEGIN EXEC msdb.dbo.sp_verify_job_identifiers '@job_name', '@job_id', @job_name OUTPUT, @job_id OUTPUT EXEC msdb.dbo.sp_update_job @job_id, @enabled = 0 SET @job_id = NULL FETCH NEXT FROM disable_jobs INTO @job_nameENDCLOSE disable_jobsDEALLOCATE disable_jobsDROP TABLE #Job_Names There is a category_name parameter to sp_update_job, so perhaps that can be used to satisfy your request. Or you can modify the select into the temp table in my code to grab the jobs that you want and then use the rest of the code.Tara Kizeraka tduggan
Maybe mine was for when you update the job step itself? Hmm... I forget what had led me down the path of calling the xp directly. If I'm not mistaken, I wasn't able to run sp_update_job sucessfully from SQLQA...*EDIT: LOL. Ok I looked at my old code and remembered why I did it that way. The requirements were to update the job start time from code.Daniel, MCP, A+SQL Server DBAwww.dallasteam.com |
|
|
Rhahn
Starting Member
9 Posts |
Posted - 2005-12-20 : 15:02:17
|
Thank you both, I've adapted the script to fix my start date problem. butEXEC msdb.dbo.sp_update_jobschedule @job_id, @active_start_date = @nextDateis throwing Server: Msg 201, Level 16, State 4, Procedure sp_update_jobschedule, Line 0Procedure 'sp_update_jobschedule' expects parameter '@name', which was not supplied.I understand it want the name of the schedule but why, can't it work like your scipt:EXEC msdb.dbo.sp_update_job @job_id, @enabled = 0where you only update the info you need updated?Here is my full procSET NOCOUNT ONCREATE TABLE #schedule( job_id UNIQUEIDENTIFIER NOT NULL, next_run_date int not null)INSERT INTO #scheduleSELECT s.job_id, s.next_run_date FROM msdb..sysjobs j (NoLock) LEFT OUTER JOIN msdb..sysjobschedules s (NoLock) ON (s.job_id = j.job_id) where j.category_id = 3 and j.enabled = 1 and s.enabled = 1ORDER BY s.job_idDECLARE @job_name SYSNAMEDECLARE @job_id UNIQUEIDENTIFIERDECLARE @nextDate intDECLARE Start_date CURSOR FOR SELECT Job_id, next_run_dateFROM #scheduleSET @job_name = NULLOPEN Start_dateFETCH NEXT FROM Start_date INTO @job_id, @nextDateWHILE @@FETCH_STATUS = 0BEGIN EXEC msdb.dbo.sp_verify_job_identifiers '@job_name', '@job_id', @job_name OUTPUT, @job_id OUTPUT EXEC msdb.dbo.sp_update_jobschedule @job_id, @active_start_date = @nextDate SET @job_name = NULL FETCH NEXT FROM Start_date INTO @job_id, @nextDateENDCLOSE Start_dateDEALLOCATE Start_dateDROP TABLE #schedule |
|
|
SQLServerDBA_Dan
Aged Yak Warrior
752 Posts |
Posted - 2005-12-20 : 15:20:56
|
quote: Originally posted by Rhahn Thank you both, I've adapted the script to fix my start date problem. butEXEC msdb.dbo.sp_update_jobschedule @job_id, @active_start_date = @nextDateis throwing Server: Msg 201, Level 16, State 4, Procedure sp_update_jobschedule, Line 0Procedure 'sp_update_jobschedule' expects parameter '@name', which was not supplied.I understand it want the name of the schedule but why, can't it work like your scipt:EXEC msdb.dbo.sp_update_job @job_id, @enabled = 0where you only update the info you need updated?
You can use the code I posted. Read it over before you run it and run it against a test job before you run it in production. I thinkg this is the problem I had when I was attempting to update the job schedule time and the code I posted was the workaround. You'll need to uncomment the part of the first update that has the active start date. If I'm not mistaken this updates the scheduled time too. So experiment on a test job first.Daniel, MCP, A+SQL Server DBAwww.dallasteam.com |
|
|
Rhahn
Starting Member
9 Posts |
Posted - 2005-12-20 : 15:29:49
|
Thanks,Just out of curiosity why wouldn’t restarting sql server agent clear its cash… that seems a lot easer than messing around with these scripts.. I’m pretty new to this admin stuff and I’m starting to see that the strait forward way to do something never wroks. |
|
|
SQLServerDBA_Dan
Aged Yak Warrior
752 Posts |
Posted - 2005-12-20 : 16:08:28
|
quote: Originally posted by Rhahn Thanks,Just out of curiosity why wouldn’t restarting sql server agent clear its cash… that seems a lot easer than messing around with these scripts.. I’m pretty new to this admin stuff and I’m starting to see that the strait forward way to do something never wroks.
I don't know. It might work... I wrote that script to update a single job rather than mess with the entire server. Keep in mind other jobs could be running. Maybe you have a job that has to run every minute and you wont be able to shut down the agent? I dunno.Daniel, MCP, A+SQL Server DBAwww.dallasteam.com |
|
|
Rhahn
Starting Member
9 Posts |
Posted - 2005-12-20 : 16:49:41
|
So Daniel, This is what I came up with. It is a hybrid of the last script to facilitate multiple jobs. I’m now getting a usage error on xp_qlagent_notify. I’m having no luck finding good documentation on this xp on Google. Server: Msg 22022, Level 16, State 1, Line 0Usage: EXECUTE xp_sqlagent_notify <operation type>, <job id>, <schedule id>, <alert id>, <action type> [, <login name>] [, <error flag>]SET NOCOUNT ONCREATE TABLE #schedule( job_id UNIQUEIDENTIFIER NOT NULL, next_run_date int not null, sched_ID int not null)INSERT INTO #scheduleSELECT s.job_id, s.next_run_date, s.schedule_id FROM msdb..sysjobs j (NoLock) LEFT OUTER JOIN msdb..sysjobschedules s (NoLock) ON (s.job_id = j.job_id) where j.category_id = 3 and j.enabled = 1 and s.enabled = 1ORDER BY s.job_idDECLARE @job_name SYSNAMEDECLARE @job_id UNIQUEIDENTIFIERDECLARE @nextDate intDECLARE @Schedule_ID intDECLARE Start_date CURSOR FOR SELECT Job_id, next_run_date, sched_IDFROM #scheduleSET @job_name = NULLOPEN Start_dateFETCH NEXT FROM Start_date INTO @job_id, @nextDate, @schedule_IDWHILE @@FETCH_STATUS = 0BEGIN EXEC msdb.dbo.sp_verify_job_identifiers '@job_name', '@job_id', @job_name OUTPUT, @job_id OUTPUT --EXEC msdb.dbo.sp_update_jobschedule @job_id, @active_start_date = @nextDate UPDATE msdb.dbo.sysjobschedules set active_start_date = @nextDate where job_id = @job_id UPDATE msdb.dbo.sysjobs SET version_number = version_number + 1, date_modified = GETDATE() WHERE (job_id = @job_id) IF (EXISTS ( SELECT s.* FROM msdb.dbo.sysjobservers s (NoLock) INNER JOIN msdb.dbo.sysjobs j (NoLock) on (j.job_id = s.job_id) WHERE server_id = 0 and j.job_id = @job_id) ) BEGIN EXEC master.dbo.xp_sqlagent_notify 'S', @job_id, @schedule_id, null, 'U', 'INSERT NT ACCOUNT HERE', 1, @@trancount END SET @job_name = NULL FETCH NEXT FROM Start_date INTO @job_id, @nextDate, @schedule_idENDCLOSE Start_dateDEALLOCATE Start_dateDROP TABLE #schedule |
|
|
Rhahn
Starting Member
9 Posts |
Posted - 2005-12-20 : 17:35:57
|
Came up with this... sp_update_jobschedule @name isn't optinal as it is in update job. but it takes a closer look at the sysntax on msdn to see that...SET NOCOUNT ONCREATE TABLE #schedule( job_id UNIQUEIDENTIFIER NOT NULL, next_run_date int not null, sname sysname not null)INSERT INTO #scheduleSELECT s.job_id, s.next_run_date, s.name FROM msdb..sysjobs j (NoLock) LEFT OUTER JOIN msdb..sysjobschedules s (NoLock) ON (s.job_id = j.job_id) where j.category_id = 3 and j.enabled = 1 and s.enabled = 1ORDER BY s.job_idDECLARE @job_name SYSNAMEDECLARE @Schedule_name SYSNAMEDECLARE @job_id UNIQUEIDENTIFIERDECLARE @nextDate intDECLARE Start_date CURSOR FOR SELECT Job_id, next_run_date, snameFROM #scheduleSET @job_name = NULLOPEN Start_dateFETCH NEXT FROM Start_date INTO @job_id, @nextDate, @Schedule_nameWHILE @@FETCH_STATUS = 0BEGIN EXEC msdb.dbo.sp_verify_job_identifiers '@job_name', '@job_id', @job_name OUTPUT, @job_id OUTPUT EXEC msdb.dbo.sp_update_jobschedule @job_id,@name=@Schedule_name, @active_start_date = @nextDate SET @job_name = NULL FETCH NEXT FROM Start_date INTO @job_id, @nextDate, @Schedule_nameENDCLOSE Start_dateDEALLOCATE Start_dateDROP TABLE #schedu |
|
|
Rhahn
Starting Member
9 Posts |
Posted - 2005-12-21 : 12:16:25
|
So I ran the script with sp_update_jobschedule and I've got the same problem as befor. I Don't understand why SQL is having such a hard time looking at its own DataBase and figuring out to start a job. |
|
|
SQLServerDBA_Dan
Aged Yak Warrior
752 Posts |
Posted - 2005-12-22 : 09:04:37
|
quote: Originally posted by Rhahn So I ran the script with sp_update_jobschedule and I've got the same problem as befor. I Don't understand why SQL is having such a hard time looking at its own DataBase and figuring out to start a job.
Is the SQL Agent started? Have you tried my script, yet? You can put it into an SP and call it from there. I'd test it on 1 job to be sure it gives the results that you want before doing a blanket update with a cursor... |
|
|
Rhahn
Starting Member
9 Posts |
Posted - 2005-12-22 : 14:39:01
|
I never could get the xp to work with the syntax in your script, and I couldn't find any thing on the web regarding it. I know the service was running b/c jobs that i did not tuch with the original enable= 0 still worked on there schedule. I had to restart the agent to get the jobs working on schedule again. |
|
|
SQLServerDBA_Dan
Aged Yak Warrior
752 Posts |
Posted - 2005-12-23 : 08:09:24
|
quote: Originally posted by Rhahn I never could get the xp to work with the syntax in your script, and I couldn't find any thing on the web regarding it.
You need to put in your user name in the xp call where it says 'INSERT NT ACCOUNT HERE'. You can get the correct user name by running "select system_user". I'm not sure what permissions your user needs but if you're a SQL Admin then permissions wont be a problem. If that doesnt work then you'll need to post the error. |
|
|
Rhahn
Starting Member
9 Posts |
Posted - 2005-12-26 : 19:08:15
|
Yeah I figured that out. The problem was your eg. dosn't have all the prams the xp wants or something.... Do you have a web page where that xp is explained? |
|
|
SQLServerDBA_Dan
Aged Yak Warrior
752 Posts |
Posted - 2005-12-27 : 08:33:33
|
What version + sp of SQL Server are you running? That code works fine for me. Keep in mind that this is commented out:UPDATE msdb..sysjobschedules SET Enabled = 1 --, active_start_date = convert(varchar(8), getdate(), 112), active_start_time = left(replace(convert(varchar(8), dateadd(n, 1, getdate()), 8), ':', ''), 4) + '00', next_run_date = convert(varchar(8), getdate(), 112), next_run_time = left(replace(convert(varchar(8), dateadd(n, 1, getdate()), 8), ':', ''), 4) + '00'FROM msdb..sysjobs j LEFT OUTER JOIN msdb..sysjobschedules s ON (s.job_id = j.job_id)WHERE j.Name = @JOBNAME Because it updates your jobschedule to the very next minute. |
|
|
|
|
|
|
|