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.
Related
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/
I had used the following SQL to list out all jobs without a stop date. I thought that I could use this to find all active jobs. What I noticed is that I have a number of jobs in this table with a null stop_execution_date. Some identical jobs (same job_id) are repeated multiple times in this table.
select job.*, activity.*
from msdb.dbo.sysjobs_view job
inner join msdb.dbo.sysjobactivity activity
on (job.job_id = activity.job_id)
where run_Requested_date is not null and stop_execution_date is null
When I run EXEC msdb.dbo.sp_help_job on these jobs, I see that they the current execution status is idle.
What do these jobs represent? Is this the behavior when the jobs are not killed properly?
Each time the SQL Agent starts, it puts a new row in syssessions and subsequently any jobs run will get that session_id in sysjobactivity. For your jobs that have a null stop date, my guess is that they're not for the "current" session which would mean that they were still running when the agent was stopped.
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)
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?
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.