I am not sure what is going on? I still get an email even though the job stopped running at 11:50 pm which clearly is less than thean 7 hours being that it started at 7 pm last night..It is suppose to email me if the job runs longer than 7 hours and for some reason yesterday it worked in test but today its not..Any ideas???
SELECT *
FROM msdb..sysjobactivity aj
JOIN msdb..sysjobs sj on sj.job_id = aj.job_id
WHERE DATEDIFF(HOUR,aj.start_execution_date,GetDate())> 7
AND aj.start_execution_date IS NOT NULL
AND sj.name = 'Nightly_Job'
and not exists ( -- make sure this is the most recent run
select 1
from msdb..sysjobactivity new
where new.job_id = aj.job_id
and new.start_execution_date > aj.start_execution_date)
if ##ROWCOUNT > 0
BEGIN
USE msdb
EXEC sp_send_dbmail
#profile_name = 'DB_Mail',
#recipients = 'xxx#yyy.com',
#subject = 'T-SQL Query Result',
#body = 'The Nightly_Job has been running 7
The problem with your query is that it only checks how long has passed since the job was started... it doesn't take into account when the job completed.
If there are no other executions of the job within 7 hours, then your check that limits the query to the most recent run doesn't exclude the previously completed job... your query then returns the job that was started over 7 hours ago, but in this case completed within 4 hours.
To fix your query to exclude completed jobs, modify your query as follows:
SELECT *
FROM
msdb..sysjobactivity aj
JOIN msdb..sysjobs sj on sj.job_id = aj.job_id
WHERE
DATEDIFF(HOUR, aj.start_execution_date,
ISNULL(aj.stop_execution_date, GetDate()) )> 7
AND sj.name = 'Nightly_Job'
AND NOT EXISTS ( -- make sure this is the most recent run
SELECT 1
FROM msdb..sysjobactivity new
WHERE new.job_id = aj.job_id
AND new.start_execution_date > aj.start_execution_date)
Related
I need to automate element in my backups schedule for differential copies.
DIFF must be performed only when job_a is not running.
The only moment when below code clashes with job_a is when job_a may be still running in scheduled time for job_b to start. I need some pattern to keep re-running job_b till job_a won't be returned by first NOT EXISTS
I did a test where job_a starts run one second before job_b. While job_b should be trying to restart as long as job_a disappears from system logs, it abandons the retries.
IF NOT EXISTS
(SELECT job.name FROM msdb.dbo.sysjobs_view job
INNER JOIN msdb.dbo.sysjobactivity activity ON job.job_id = activity.job_id
INNER JOIN msdb.dbo.syssessions sess ON sess.session_id = activity.session_id
INNER JOIN (SELECT MAX(agent_start_date) AS max_agent_start_date FROM msdb.dbo.syssessions) sess_max ON sess.agent_start_date = sess_max.max_agent_start_date
WHERE run_requested_date IS NOT NULL
AND stop_execution_date IS NULL
AND job.name = 'job_a')
BEGIN
DECLARE #path_diff varchar(max)
SET #path_diff = 'H:\MSSQL13.MSSQLSERVER\MSSQL\Backup\dev\db_name' + CONVERT(varchar, GETDATE(), 112) + REPLACE(CONVERT(varchar, GETDATE(), 114),':','') + '_DIFF_COMP.BAK'
BACKUP DATABASE [db_name] TO DISK = #path_diff WITH COMPRESSION, DIFFERENTIAL , STATS = 10
END
--need a step that will re-start the job once job_a doesn't appear in NOT EXISTS
ELSE
EXEC msdb.dbo.sp_stop_job N'job_b'
PRINT 'Full backup is taking longer then usual, please inspect!'
EXEC msdb.dbo.sp_start_job N'job_b'
we have a sql server agent job which is running two sql servant jobs.The job is designed in the way that the second job will wait till the first job completed. But sometimes the wait is not working and it causes both jobs ends up running at same time. This causes failure of both jobs. We uses below code for waiting mechanism.
WHILE
(
SELECT COUNT(*) AS cnt
FROM msdb.dbo.sysjobs J
INNER JOIN msdb.dbo.sysjobactivity JA
ON J.job_id = JA.job_id
WHERE start_execution_date IS NOT NULL
AND stop_execution_date IS NULL
AND J.name = "first job name"
AND last_executed_step_date > DATEADD(DD,-1,GETDATE())--//Added to bypass historical corrupt data
) > 0
BEGIN
--WAIT
WAITFOR DELAY '00:01';
END
any suggestion why this is not working sometimes?
I have a situation where I have 1 package (Package A) that take about 3 min to complete and another package (Package B) that takes about 4 min to complete. I need package A to run every 5 min via a job and package B to run every 15 min. However package B can only run after package A has been completed.
Example
5- Package A runs
10- Package A runs
15- Package A runs and then Package B
20- Package A runs
25- Package A runs
30- Package A runs and then Package B
Is there any way to schedule jobs to meet the requirements above?
Really appreciate your help. Thanks in advance!
for package B i would just put in logic to check if package A has stopped running
the wait script would be
WHILE EXISTS (
SELECT
*
FROM
msdb.dbo.sysjobs_view job
JOIN
msdb.dbo.sysjobactivity activity
ON
job.job_id = activity.job_id
JOIN
msdb.dbo.syssessions sess
ON
sess.session_id = activity.session_id
JOIN
(
SELECT
MAX( agent_start_date ) AS max_agent_start_date
FROM
msdb.dbo.syssessions
) sess_max
ON
sess.agent_start_date = sess_max.max_agent_start_date
WHERE
run_requested_date IS NOT NULL AND stop_execution_date IS NULL
AND job.name = 'package A')
BEGIN
WAITFOR DELAY '00:00:30';
END
This would check every 30 seconds if package A has stopped running.
Alternatively, you create a table that would keep track of job status and have A write to it to keep track of the status.
I've been working in a time attendance application and need some enlightment.
This is my current SQL query:
SELECT M.IdMarcacao, M.IdFuncionario, M.Data, M.Hora, Extra,
(M.Hora-(convert(varchar(11),dateadd(ms,cast(Extra*3600000 as bigint),'12/30/1899'),108))) as teste
FROM TimeReport.dbo.Marcacoes M
INNER JOIN TimeReport.dbo.Resultados R ON M.IdFuncionario = R.IdFuncionario
AND M.Data = R.Data
WHERE (R.Extra <> 0 AND M.[Tipo Marcacao] = 'SAI')
AND M.Hora=(SELECT max(hora)
FROM timereport.dbo.marcacoes
WHERE data = M.Data)
This returns the lines where:
1 - The person has made overtime hours.
2 - The last logout time
3 - The total of overtime hours.
4 - The difference between logout time and overtime = schedule time
5 - Make sure it's a logout time (Tipo = SAI)
Without entering into much detail about the application itself, what I really need is to turn this into an UPDATE statement.
I used to do this:
UPDATE [TimeReport].[dbo].[Marcacoes]
SET [Hora] = [Hora] - convert(datetime,'01:00:00',108)
WHERE [Hora] > '1899-12-30 19:00:00.000'
For every single hour until 0pm :( It's not a good solution I know.
This update, will change the original logout time to minus 1 hour if the worker left at 19h, when the company schedule is 18h.
What I am trying to do, is simplify and automate the process.
Which brings my previous question... How can I do a update based on that select statement?
Or... in other words, something like:
UPDATE TimeReport.dbo.Marcacoes
SET Hora = (The value from the statement above, field "teste")
WHERE IdMarcacao = IdMarcacao(from the statement above)
Note: This "IdMarcacao" is a unique identifier for the row.
Thank you!
update TimeReport.dbo.Marcacoes set
Hora = (M.Hora-(convert(varchar(11),dateadd(ms,cast(Extra*3600000 as bigint),'12/30/1899'),108)))
--select M.IdMarcacao, M.IdFuncionario, M.Data, M.Hora, Extra, (M.Hora-(convert(varchar(11),dateadd(ms,cast(Extra*3600000 as bigint),'12/30/1899'),108))) teste
from TimeReport.dbo.Marcacoes M
INNER JOIN TimeReport.dbo.Resultados R ON M.IdFuncionario = R.IdFuncionario AND M.Data = R.Data
WHERE (R.Extra <> 0 AND M.[Tipo Marcacao] = 'SAI')
AND M.Hora=(select max(hora) from timereport.dbo.marcacoes where data = M.Data)
Does anyone know the query the last synchronization date from sql server (2008).
It is the same information displayed in replication monitor, but I want to be able to get that date from a query.
I created a view like this to get last date by the subscriber
select subscriber_name, max(start_time) as last_sync
from msMerge_sessions inner join msMerge_agents
on msmerge_agents.id = msmerge_sessions.agent_id
group by subscriber_name
I called the view 'LastSync' - I then joined that view like this to get a representation similar to what the replication monitor shows.
SELECT dbo.LastSync.id, dbo.LastSync.subscriber_name, dbo.LastSync.creation_date, dbo.LastSync.last_sync,
distribution.dbo.MSmerge_sessions.estimated_upload_changes + distribution.dbo.MSmerge_sessions.estimated_download_changes AS estimate_rows,
distribution.dbo.MSmerge_sessions.upload_inserts + distribution.dbo.MSmerge_sessions.upload_updates + distribution.dbo.MSmerge_sessions.upload_deletes + distribution.dbo.MSmerge_sessions.download_inserts
+ distribution.dbo.MSmerge_sessions.download_updates + distribution.dbo.MSmerge_sessions.download_deletes AS actual_rows,
distribution.dbo.MSmerge_sessions.duration AS total_seconds, distribution.dbo.MSmerge_sessions.percent_complete,
distribution.dbo.MSmerge_sessions.delivery_rate, CASE (runstatus)
WHEN 1 THEN 'Start' WHEN 2 THEN 'Succeed' WHEN 3 THEN 'In Progress' WHEN 4 THEN 'Idle' WHEN 5 THEN 'Retry' WHEN 6 THEN 'Fail' END AS Status
FROM distribution.dbo.MSmerge_sessions INNER JOIN
dbo.LastSync ON dbo.LastSync.id = distribution.dbo.MSmerge_sessions.agent_id AND distribution.dbo.MSmerge_sessions.start_time = dbo.LastSync.last_sync
You can see a lot of info about merge sessions by using the system table msMerge_sessions:
select * from msMerge_sessions
Depending on the info you need, use the other system tables available in your database.
For Answered Number 3
Great Effort but there're some modification On view for ability running Query
---- Create View LastSync as below
Create View LastSync As
select subscriber_name, max(start_time) as last_sync, ID, creation_date
from msMerge_sessions inner join msMerge_agents
on msmerge_agents.id = msmerge_sessions.agent_id
group by subscriber_name, ID, creation_date
Go
---- Run Below Query
SELECT dbo.LastSync.id, dbo.LastSync.subscriber_name,
dbo.LastSync.creation_date, dbo.LastSync.last_sync,
distribution.dbo.MSmerge_sessions.estimated_upload_changes +
distribution.dbo.MSmerge_sessions.estimated_download_changes AS
estimate_rows, distribution.dbo.MSmerge_sessions.upload_inserts +
distribution.dbo.MSmerge_sessions.upload_updates +
distribution.dbo.MSmerge_sessions.upload_deletes +
distribution.dbo.MSmerge_sessions.download_inserts
+ distribution.dbo.MSmerge_sessions.download_updates + distribution.dbo.MSmerge_sessions.download_deletes AS actual_rows,
distribution.dbo.MSmerge_sessions.duration AS total_seconds,
distribution.dbo.MSmerge_sessions.percent_complete,
distribution.dbo.MSmerge_sessions.delivery_rate, CASE (runstatus)
WHEN 1 THEN 'Start' WHEN 2 THEN 'Succeed' WHEN 3 THEN 'In Progress'
WHEN 4 THEN 'Idle' WHEN 5 THEN 'Retry' WHEN 6 THEN 'Fail' END AS
Status FROM distribution.dbo.MSmerge_sessions INNER JOIN dbo.LastSync
ON dbo.LastSync.id = distribution.dbo.MSmerge_sessions.agent_id AND
distribution.dbo.MSmerge_sessions.start_time = dbo.LastSync.last_sync
-- Good Luck