Where to find date & time of currently running SQL agent job STEP? - sql-server

I want to query a view or table for the currently running SQL agent job steps and when did they start.
I've tried queries below but it gives me JOB datetime rather then step datetime.
select top 100 * from msdb.dbo.sysjobsteps
select top 100 * from msdb.dbo.sysjobstepslogs
select top 100 * from msdb.dbo.sysjobhistory
exec master.dbo.xp_sqlagent_enum_jobs 1 , garbage -- gives me currently running job step
Screen Shot of desired values below from SQL Activity Monitor.

try the following
SELECT
ja.job_id as JobId,
j.name AS JobName,
ja.start_execution_date as StartDn,
ISNULL(last_executed_step_id,0)+1 AS CurrentStepId
FROM msdb.dbo.sysjobactivity ja
LEFT JOIN msdb.dbo.sysjobhistory jh ON ja.job_history_id = jh.instance_id
INNER JOIN msdb.dbo.sysjobs j ON ja.job_id = j.job_id
INNER JOIN msdb.dbo.sysjobsteps js ON ja.job_id = js.job_id AND ISNULL(ja.last_executed_step_id,0)+1 = js.step_id
INNER JOIN msdb.dbo.syssessions r ON r.session_id = ja.session_id
WHERE start_execution_date is not null
AND stop_execution_date is null;
You might check this article for further information
hope this will help you

/* Hank Freeman */
use master
go
SELECT
ja.job_id,
j.name AS job_name,
ja.start_execution_date,
--2019-06-10 18:54:31.000
getdate() as 'NOW',
'0'+Cast(Datepart(hh,(getdate() - ja.start_execution_date)) as char(2)) + ':' +
Cast(Datepart(n,(getdate() - ja.start_execution_date)) as char(2)) + ':' +
'0'+Cast(Datepart(ss,(getdate() - ja.start_execution_date)) as char(2)) as 'Duration',
Cast(DATEDIFF(n,ja.start_execution_date,getdate()) as char(5)) as 'Duration_Mins',
ISNULL(last_executed_step_id,0)+1 AS cur_exec_step_id,
Js.step_name
FROM msdb.dbo.sysjobactivity ja
LEFT JOIN msdb.dbo.sysjobhistory jh
ON ja.job_history_id = jh.instance_id
JOIN msdb.dbo.sysjobs j
ON ja.job_id = j.job_id
JOIN msdb.dbo.sysjobsteps js
ON ja.job_id = js.job_id
AND ISNULL(ja.last_executed_step_id,0)+1 = js.step_id
WHERE ja.session_id = (
SELECT TOP 1 session_id
FROM msdb.dbo.syssessions
ORDER BY session_id DESC
)
AND start_execution_date is not null
AND stop_execution_date is null
order by 2
;

Related

Putting many tables in to one table in SQL Server?

I'm trying to insert the result from a query into a new table.
I'm using this query and want to gather the result into a single table.
The query (I found somewhere) looks like this:
USE [AdventureWorksDW2012]
SELECT
OBJECT_SCHEMA_NAME(T.[object_id],DB_ID()) AS [Schema],
T.[name] AS [table_name],
AC.[name] AS [column_name],
TY.[name] AS system_data_type,
AC.[max_length],
AC.[precision], AC.[scale],
AC.[is_nullable], AC.[is_ansi_padded]
FROM
sys.[tables] AS T
INNER JOIN
sys.[all_columns] AC ON T.[object_id] = AC.[object_id]
INNER JOIN
sys.[types] TY ON AC.[system_type_id] = TY.[system_type_id]
AND AC.[user_type_id] = TY.[user_type_id]
WHERE
T.[is_ms_shipped] = 0
ORDER BY
T.[name], AC.[column_id];
Try using an INTO clause like this:
USE [AdventureWorksDW2012]
SELECT OBJECT_SCHEMA_NAME(T.[object_id],DB_ID()) AS [Schema],
T.[name] AS [table_name], AC.[name] AS [column_name],
TY.[name] AS system_data_type, AC.[max_length],
AC.[precision], AC.[scale], AC.[is_nullable], AC.[is_ansi_padded]
INTO dbo.MyNewTable
FROM sys.[tables] AS T
INNER JOIN sys.[all_columns] AC ON T.[object_id] = AC.[object_id]
INNER JOIN sys.[types] TY ON AC.[system_type_id] = TY.[system_type_id]
AND AC.[user_type_id] = TY.[user_type_id]
WHERE T.[is_ms_shipped] = 0
ORDER BY T.[name], AC.[column_id]
;
Use INTO clause as next:-
USE [AdventureWorksDW2012]
SELECT OBJECT_SCHEMA_NAME(T.[object_id],DB_ID()) AS [Schema],
T.[name] AS [table_name], AC.[name] AS [column_name],
TY.[name] AS system_data_type, AC.[max_length],
AC.[precision], AC.[scale], AC.[is_nullable], AC.[is_ansi_padded]
Into New_table -- this line is added.
FROM sys.[tables] AS T
INNER JOIN sys.[all_columns] AC ON T.[object_id] = AC.[object_id]
INNER JOIN sys.[types] TY ON AC.[system_type_id] = TY.[system_type_id] AND AC.[user_type_id] = TY.[user_type_id]
WHERE T.[is_ms_shipped] = 0
ORDER BY T.[name], AC.[column_id]
The sample code is
Select *
Into New_table
From Exist_Table
and as MSDN says:-
SELECT…INTO creates a new table in the default filegroup and inserts
the resulting rows from the query into it.

How to display if a field exists in other table?

I want to show/display if the product is found each transaction.
tblProducts
ID PRODCODE PRODDESC
1 PFX-321 MILK CHOCO
2 PDF-875 COFFEE JELLY
3 PWA-718 MILK SHAKE
tblTransactions
TCODE PRODCODE
BMX2213391 PFX-321
BMX2213391 PDF-875
PDFSD92851 PDF-875
I want the results to display like this
TCODE PRODCODE FOUND
BMX2213391 PFX-321 YES
BMX2213391 PDF-875 YES
BMX2213391 PWA-718 NO
PDFSD92851 PFX-321 NO
PDFSD92851 PDF-875 YES
PDFSD92851 PWA-718 NO
I tried, INNER JOIN, FULL OUTER JOIN, LEFT JOIN and RIGHT JOIN but I don't get the exact data I need.
Here are the queries I test.
SELECT * FROM tblProducts a INNER JOIN tblTransactions b ON a.PRODCODE = b.PRODCODE
SELECT * FROM tblProducts a FULL OUTER JOIN tblTransactions b ON a.PRODCODE = b.PRODCODE
SELECT * FROM tblProducts a LEFT JOIN tblTransactions b ON a.PRODCODE = b.PRODCODE
SELECT * FROM tblProducts a RIGHT JOIN tblTransactions b ON a.PRODCODE = b.PRODCODE
I'm pretty sure this works - SQLFiddle here: http://sqlfiddle.com/#!3/65eb1/23
WITH AllVals AS
(SELECT a.PRODCODE, b.TCODE
FROM tblProducts a
CROSS JOIN tblTransactions b)
SELECT DISTINCT c.PRODCODE,
c.TCODE,
CASE WHEN d.PRODCODE IS NULL THEN 'NO' ELSE 'YES' END AS FOUND
FROM AllVals c
LEFT OUTER JOIN tblTransactions d
ON c.PRODCODE = d.PRODCODE
AND c.TCODE = d.TCODE
http://sqlfiddle.com/#!3/65eb1/24
select DT.TCODE, DT.PRODCODE, case when (Tr2.TCODE IS null and Tr2.PRODCODE IS null) then 'No' else 'Yes' END as FOUND
from tblTransactions Tr2 right join
(
select distinct Tr.TCODE, p.PRODCODE
from tblProducts p cross join tblTransactions Tr
) DT
on DT.PRODCODE = Tr2.PRODCODE and DT.TCODE = Tr2.TCODE;

Creating an SQL query to show clients owing payments

I'm having a lot of trouble trying to produce a query that displays the client names, contact numbers, email addresses and total unpaid job costs of any clients who have a total (sum) of at least $500 in unpaid jobs.
I then have to order the results so that the largest amount owing is at the top.
So far I have come up with this query
SELECT
j.job_id,
c.name + c.surname,
c.phone,
c.email_address,
SUM(jt.cost * (DATEDIFF(mi, timestart, timecomplete)))
FROM client as c
LEFT OUTER JOIN job AS j ON c.tax_file_number = c.tax_file_number
LEFT OUTER JOIN job_type AS jt ON j.jobtype_id = jt.jobtype_id
WHERE SUM(jt.cost * (DATEDIFF(mi, timecomplete, timestart) > 500
ORDER BY SUM(jt.cost * (DATEDIFF(mi, timecomplete, timestart))) DESC;
Any help would be appreciated
Guessing here since your requirements are not clear, but I think you want this:
WITH jobinfo as
(
SELECT j.client_id, SUM(jt.cost * (DATEDIFF(mi, timecomplete, timestart))) as cost
FROM job as j
JOIN job_type as jt ON j.jobtype_id = jt.jobtype_id
GROUP BY j.client_id
)
SELECT
c.client_id,
c.name + c.surname,
c.phone,
c.email_address,
j.cost
FROM client as c
JOIN jobinfo j ON c.client_id= j.client_id
WHERE j.cost > 500
ORDER BY j.cost DESC
declare _sum int,
set _sum= (select SUM(jt.cost * (DATEDIFF(mi, timecomplete, timestart))) from job_type) SELECT j.job_id, c.name + c.surname, c.phone, c.email_address, SUM(jt.cost * (DATEDIFF(mi, timestart, timecomplete))) FROM client as c LEFT OUTER JOIN job AS j ON c.tax_file_number = c.tax_file_number LEFT OUTER JOIN job_type AS jt ON j.jobtype_id = jt.jobtype_id WHERE _sum > 500
Please try the following. Aggregate function (SUM, COUNT, etc) are not allowed on the WHERE clause, you should use HAVING for those.
SELECT
j.job_id,
c.name + c.surname,
c.phone,
c.email_address,
SUM(jt.cost * (DATEDIFF(mi, timestart, timecomplete)))
FROM client as c
LEFT OUTER JOIN job AS j ON a.tax_file_number = c.tax_file_number
LEFT OUTER JOIN job_type AS jt ON j.jobtype_id = jt.jobtype_id
HAVING SUM(jt.cost * (DATEDIFF(mi, timecomplete, timestart) > 500
ORDER BY SUM(jt.cost * (DATEDIFF(mi, timecomplete, timestart))) DESC;
EDIT:
Fixed ON a.tax_file_number = c.tax_file_number

SQL Scheduled job query, duration of last runs?

Previously used this SQL Agent Jobs, how to document to get information about all SQL Scheduled jobs.
How can I find out the duration of the last run for each job? I need seconds, minutes, and hours (hopefully not, but I'm afraid).
Can anyone give some insight into how I could query this?
Assuming you're not going to have any jobs that run longer than 999 hours, this should give you a good starting point:
SELECT
j.name,
h.run_status,
durationHHMMSS = STUFF(STUFF(REPLACE(STR(h.run_duration,7,0),
' ','0'),4,0,':'),7,0,':'),
[start_date] = CONVERT(DATETIME, RTRIM(run_date) + ' '
+ STUFF(STUFF(REPLACE(STR(RTRIM(h.run_time),6,0),
' ','0'),3,0,':'),6,0,':'))
FROM
msdb.dbo.sysjobs AS j
INNER JOIN
(
SELECT job_id, instance_id = MAX(instance_id)
FROM msdb.dbo.sysjobhistory
GROUP BY job_id
) AS l
ON j.job_id = l.job_id
INNER JOIN
msdb.dbo.sysjobhistory AS h
ON h.job_id = l.job_id
AND h.instance_id = l.instance_id
ORDER BY
CONVERT(INT, h.run_duration) DESC,
[start_date] DESC;
Aaron, I've made some tweaks to your script, which include the next scheduled run time (start date is the initial start date of the schedule, not necessarily the next start date for the job), and some various other checks. Thanks for the framework though; very helpful starting point indeed!
I also took some logic from an oldie but goodie (here).
USE msdb
Go
SELECT j.Name AS 'Job Name',
'"' + NULLIF(j.Description, 'No description available.') + '"' AS 'Description',
SUSER_SNAME(j.owner_sid) AS 'Job Owner',
(SELECT COUNT(step_id) FROM dbo.sysjobsteps WHERE job_id = j.job_id) AS 'Number of Steps',
(SELECT COUNT(step_id) FROM dbo.sysjobsteps WHERE job_id = j.job_id AND command LIKE '%xp_cmdshell%') AS 'has_xpcmdshell',
(SELECT COUNT(step_id) FROM dbo.sysjobsteps WHERE job_id = j.job_id AND command LIKE '%msdb%job%') AS 'has_jobstartstopupdate',
(SELECT COUNT(step_id) FROM dbo.sysjobsteps WHERE job_id = j.job_id AND command LIKE '%ftp%') AS 'has_ftp',
'Job Enabled' = CASE j.Enabled
WHEN 1 THEN 'Yes'
WHEN 0 THEN 'No'
END,
'Frequency' = CASE s.freq_type
WHEN 1 THEN 'Once'
WHEN 4 THEN 'Daily'
WHEN 8 THEN 'Weekly'
WHEN 16 THEN 'Monthly'
WHEN 32 THEN 'Monthly relative'
WHEN 64 THEN 'When SQLServer Agent starts'
END,
CASE(s.freq_subday_interval)
WHEN 0 THEN 'Once'
ELSE cast('Every '
+ right(s.freq_subday_interval,2)
+ ' '
+ CASE(s.freq_subday_type)
WHEN 1 THEN 'Once'
WHEN 4 THEN 'Minutes'
WHEN 8 THEN 'Hours'
END as char(16))
END as 'Subday Frequency',
'Next Start Date'= CONVERT(DATETIME, RTRIM(NULLIF(js.next_run_date, 0)) + ' '
+ STUFF(STUFF(REPLACE(STR(RTRIM(js.next_run_time),6,0),
' ','0'),3,0,':'),6,0,':')),
'Max Duration' = STUFF(STUFF(REPLACE(STR(maxdur.run_duration,7,0),
' ','0'),4,0,':'),7,0,':'),
'Last Run Duration' = STUFF(STUFF(REPLACE(STR(lastrun.run_duration,7,0),
' ','0'),4,0,':'),7,0,':'),
'Last Start Date' = CONVERT(DATETIME, RTRIM(lastrun.run_date) + ' '
+ STUFF(STUFF(REPLACE(STR(RTRIM(lastrun.run_time),6,0),
' ','0'),3,0,':'),6,0,':')),
'Last Run Message' = lastrun.message
FROM dbo.sysjobs j
LEFT OUTER JOIN dbo.sysjobschedules js
ON j.job_id = js.job_id
LEFT OUTER JOIN dbo.sysschedules s
ON js.schedule_id = s.schedule_id
LEFT OUTER JOIN (SELECT job_id, max(run_duration) AS run_duration
FROM dbo.sysjobhistory
GROUP BY job_id) maxdur
ON j.job_id = maxdur.job_id
-- INNER JOIN -- Swap Join Types if you don't want to include jobs that have never run
LEFT OUTER JOIN
(SELECT j1.job_id, j1.run_duration, j1.run_date, j1.run_time, j1.message
FROM dbo.sysjobhistory j1
WHERE instance_id = (SELECT MAX(instance_id)
FROM dbo.sysjobhistory j2
WHERE j2.job_id = j1.job_id)) lastrun
ON j.job_id = lastrun.job_id
ORDER BY [Job Name]

How can i link a sql server job name

to the SSRS report server process that uses it? the name looks like a guid, but i need to find the reporting services reports that use it.
thanks very much
Here's a query I blogged about a while back that does the join:
;WITH cte (job_id, job_name, execution_time, execution_order)
AS
(
SELECT DISTINCT j.job_id
,j.name
,CONVERT(datetime, STUFF(STUFF(run_date,7,0,'/'),5,0,'/')
+ SPACE(1)
+ STUFF(STUFF(RIGHT('000000' + CONVERT(varchar(20), run_time), 6),5,0,':'),3,0,':'))
,ROW_NUMBER() OVER (PARTITION BY j.job_id ORDER BY CONVERT(datetime, STUFF(STUFF(run_date,7,0,'/'),5,0,'/')
+ SPACE(1)
+ STUFF(STUFF(RIGHT('000000' + CONVERT(varchar(20), run_time), 6),5,0,':'),3,0,':')) DESC)
FROM msdb.dbo.sysjobs j
INNER JOIN msdb.dbo.syscategories c ON j.category_id = c.category_id
LEFT OUTER JOIN msdb.dbo.sysjobhistory jh ON j.job_id = jh.job_id
WHERE c.name ='Report Server'
)
SELECT
x.job_name
,c.name
,x.execution_time
,c.path
,su.description
,CONVERT(varchar(max), su.ExtensionSettings) as ExtensionSettings
,'EXEC msdb..sp_start_job ''' + x.job_name + '''' as SQLStatement
FROM cte x
INNER JOIN dbo.Schedule sc ON x.job_name = CONVERT(varchar(100), sc.ScheduleID)
INNER JOIN dbo.ReportSchedule rs ON sc.ScheduleID = rs.ScheduleID
INNER JOIN dbo.Subscriptions su ON rs.SubscriptionID = su.SubscriptionID
INNER JOIN dbo.Catalog c ON su.Report_OID = c.ItemID
WHERE execution_order = 1
ORDER BY 3, 2
There doesn't appear to be a straightforward method to find this out.
The following query lists the subscription IDs and the reports to which they link
select s.SubscriptionID, c.Path
from ReportServer.dbo.Subscriptions as s
JOIN ReportServer.dbo.Catalog as c
on ItemID = Report_OID
The subscription ID is then referenced inside the job step, in the following format.
exec ReportServer.dbo.AddEvent #EventType='TimedSubscription', #EventData='~subscriptionID~'
It should be possible to write a query to join it all together, but I don't have time right now. I will try and update the question later.

Resources