Changing SQL Agent Job Schedule time programmaticaly doesn't work - sql-server

I have an SQL Agent Job, that is supposed to be fired everyday at provided time. If I change the schedule time manualy from Management Studio, it works fine, but i need to change the time using stored procedure as below:
update s set
s.active_start_time = #time
from msdb..sysjobs j
left join msdb..sysjobschedules js on j.job_id = js.job_id
left join msdb..sysschedules s on js.schedule_id = s.schedule_id
where j.name = 'MyJobName'
And guess what? After running such procedure, when I check scheduled time in Management Studio, it's updated correctly, BUT obviously Job ignores that.
I even found out, that this Job keeps somewhere the old schedule time that was set manually, and run using that one - if I for example manually set time to 10:45 AM, and then quickly change time using procedure to 10:55 AM, even if schedule time inside Management Studio looks to be updated, Job still will run at 10:45...
Any thoughts what can be wrong?

Related

Microsoft SQL Server Agent Job: Get Schedule that triggered the Job

I have SQL Server Agent Job on my System that copies data into at table for later evaluation purposes. The Job runs on two types of schedules every Friday every week and last day of the month. The target data records should also contain a column indicating the schedule that originally triggered the job. But I found no way so far to receive this data as parameter or so. I'm using a Microsoft SQL Server 2017.
I did a web search but maybe searched for the wrong keywords. I also thought about comparing current time to expected runtime per schedule but that seemed to be not a fault tolerant option to me.
I like to fill a column "schedule" with values like "End of week", "End of month"
sys tables are your friend here. Documentation
sysjobs has your job information.
sysjobschedules links your job to its schedule.
sysschedules has your schedule info.
SELECT j.*
, s.*
FROM sysjobs j
JOIN sysjobschedules js ON j.id = js.job_id
JOIN sysschedules s ON js.schedule_id = s.schedule_id
WHERE j.name = 'your job name here'
After long search and analyzing I finally found a solution that at least fit my needs:
The undocumented and unsupport stored procedures provides the schedule that triggered a job ind Column Request Source ID:
EXEC master.dbo.xp_sqlagent_enum_jobs 1, garbage
see also: https://am2.co/2016/02/xp_sqlagent_enum_jobs_alt/

Schedule Job in SQL Server 2017 Management Studio

I have a table which stores Finance Fiscal Period Close dates.
I wanted to run a stored procedure on those dates. How can I link the database table to pick the date and time from those tables and run the job accordingly?
These dates usually get populated at the beginning of the FY but can get update between.
You can create a job that runs daily with a T-SQL Script step that executes something like this:
IF EXISTS(SELECT *
FROM FinanceFiscalPeriodCloseDates
WHERE CloseDate = CAST(GETDATE() AS DATE())
EXECUTE SomeProcedure;
If you don't know how to create and schedule a job, then the problem might be broader.
You cannot create a dynamic schedule on which a job will run.
What you can do is schedule the job to run every day, and have the first step of the stored proc be to check if today's date is in the table. If yes, then proceed with the other steps. If no, then don't do anything.

How to monitor an SQL Server Agent Job that runs after being triggered

I'm running SQL Server 2008 and I have 3 agent jobs set up to run one after the other because the success of the second depends on the first, etc.
Every other job I have is independent and I monitor using a script that incorporates MSDB..sysjobhistory run_status field, among others.
I want to know if there is a way to specifically find all jobs that never started for a specific day. I know that I can think of the problem the other way and say job 2 couldn't possibly run if job 1 failed; however, I'm looking for a more general purpose solution so in case I need to create other jobs that are linked similarly I won't have to hard code more logic into my nightly report.
Any suggestions are welcome!
The MSDB..sysjobservers table holds a single record for every agent job in your server, and includes the field last_run_date which makes it easy to tell which jobs haven't run in the last 24 hours. My query looks something like this
SELECT A.name AS [Name]
,##servername AS [Server]
,'Yes' AS [Critical]
FROM MSDB.dbo.sysjobs A
INNER JOIN MSDB.dbo.sysjobservers B ON A.job_id = B.job_id
WHERE A.name LIKE '2%SPRING%'
AND DATEDIFF(DAY, CONVERT(DATETIME, CONVERT(CHAR(8),B.last_run_date)), GETDATE( )) > 1)

Manipulate data when a job is running in sql server

I have a scheduled job in Sql Server 2012. When the job runs every 20 mins, it executes a stored procedure and fills a new table. It takes a lot of time to update the table every time and I don't want an empty table when the job is running.
This is something I'm trying,
IF EXISTS(SELECT 1
FROM msdb.dbo.sysjobs J
JOIN msdb.dbo.sysjobactivity A
ON A.job_id=J.job_id
WHERE J.name=N'MyJobName'
AND A.run_requested_date IS NOT NULL
AND A.stop_execution_date IS NULL
)
PRINT 'The job is running!'
ELSE
PRINT 'The job is not running.'
So, basically when the job is running, instead of printing, I want to return data from a new table or something. The idea is, I do not want an empty data set even when the job is running.
Any ideas will be helpful.
Thanks.

Trigger that only runs runs once per day

This trigger backs up data from dbo.node to dbo.nodearchive. While backups are important, I only need to do this once per day. Note that there is a field called dbo.NodeArchive.versionDate (smalldDatetime).
CREATE TRIGGER [dbo].[Node_update]
ON [dbo].[Node]
for UPDATE
AS
BEGIN
INSERT INTO dbo.NodeArchive ([NodeID]
,[ParentNodeID]
,[Slug]
,[xmlTitle]
...
,[ModifyBy]
,[ModifyDate]
,[CreateBy]
,[CreateDate])
SELECT [deleted].[NodeID]
,[deleted].[ParentNodeID]
,[deleted].[Slug]
,[deleted].[xmlTitle]
...
,[deleted].[ModifyBy]
,[deleted].[ModifyDate]
,[deleted].[CreateBy]
,[deleted].[CreateDate]
FROM [deleted] LEFT JOIN dbo.Node
ON [deleted].NodeID = dbo.Node.NodeID
WHERE deleted.ModifyDate <> dbo.Node.ModifyDate
END
GO
I am looking to backup changes, but never more than one backup version per day. If there is no change, there is no backup.
That's not a trigger anymore - that'll be a scheduled job. Triggers by their very definition execute whenever a given operation (INSERT, DELETE, UPDATE) happens.
Use the SQL Server Agent facility to schedule that T-SQL code to run once per day.
Read all about SQL Server Agent Jobs in the SQL Server Books Online on MSDN
Update: so if I understand correctly: you want to have an UPDATE trigger - but that trigger would only record the NodeID that were affected, into a "these nodes need to be backed up at night" sort of table. Then, at night, you would have a SQL Agent Job that runs and that scans that "work table" and for all NodeID values stored in there, it would then execute that T-SQL statement to copy their data into the NodeArchive table.
With this approach, if your nodes with NodeID = 42 changes ten times, you'll still only have a single entry NodeID = 42 in your work table, and the nightly backup job would then copy that node only once into the NodeArchive.
With this approach, you can decouple the actual copying (which might take time) from the update process. The UPDATE trigger only records which NodeID rows need processing - the actual processing then happens sometime later, at an off-peak hour, without disturbing users of your system.

Resources