Notification that a JOB did not start in SQL Server Agent 2008 - sql-server-2008

We are able to send notification regarding failure/success of a job but if a job does not start on its scheduled time can we create a script which will send a notification to my mail box saying that the "JOB did not start'?

Per documentation, below are the only cases which can be notified. So, JOB Doesn't start isn't even in the list; which means that you can't set a notification for that.
But my thinking is that, If you know that in a day you are supposed to get N email notification for N jobs, you can check that and find out which job didn't run.
When the job succeeds to notify the operator when the job completes successfully.
When the job fails to notify the operator when the job completes unsuccessfully.
When the job completes to notify the operator regardless of completion status.

SELECT DISTINCT
J.NAME AS 'JOBNAME',
MSDB.DBO.AGENT_DATETIME(RUN_DATE, RUN_TIME) AS 'RUNDATETIME'
INTO #TEMP
FROM MSDB.DBO.SYSJOBS J
INNER JOIN MSDB.DBO.SYSJOBHISTORY H
ON J.JOB_ID = H.JOB_ID
WHERE J.ENABLED = 1 --ONLY ENABLED JOBS
ORDER BY JOBNAME, RUNDATETIME DESC
IF NOT EXISTS (
SELECT * FROM #TEMP
WHERE JOBNNAME = 'JOBNAME'
AND RUNDATETIME = 'RUNDATETIME')
BEGIN
SEND AN EMAIL
END
There's no simple way to do this, but you can query the job history tables to check if the job start time has been logged. If it hasn't you can use an IF expression to send you an email.
Thanks.

Related

Converting H2/MySQL query to Postgres/cockroach

I want to convert following —admittedly bad— query from H2/MySQL to Postgres/cockroach:
SET #UPDATE_TRANSFER=
(select count(*) from transfer where id=‘+transfer_id+' and consumed=false)>0;
update balance_address set balance =
case when #UPDATE_TRANSFER then balance +
(select value from transaction where transfer_id=‘+id+' and t_index=0)
else balance end where address =
(select address from transaction where transfer_id=‘+id+' and t_index=0)
There are three tables involved in this query: balance_address, bundle, and transaction. The goal of the query is to update the overall balance when a fund transfer happens.
A transfer can have many transaction bundled together. For instance, let’s assume Paul has $20 in his account and he wants to send $3 to Jane. This will result in 4 transactions:
One that adds $3 into Jane’s account
One transaction that removes the $20 from Paul account
One transactions that changes Paul account to 0
One transaction that puts to remainder of Paul funds in a new address; still belonging to him.
Each of these transaction in the whole transfer bundle has an index and a value. As you see above. So the goal of this update query is to update Jane’s account.
The challenge is that this transfer can be processed by many servers in parallel and there is no distributed lock. So, if we naively process in parallel, each server will increment Jane’s account, leading to erroneous results.
To prevent this, the balance_address table has a column called consumed. The first server that updates the balance, sets the transfer to consumed=true. Other servers or threads can only update if consumed is false.
So, my goal is to 1) improve this query and 2) rewrite it to work with posters. Right now, the variable construct is not accepted already.
PS. I cannot change the data model.
CockroachDB doesn't have variables, but the #UPDATE_TRANSFER variable is only used once, so you can just substitute the subquery inline:
update balance_address set balance =
case
when (select count(*) from transfer where id=$1 and consumed=false)>0
then balance + (select value from transaction where transfer_id=$1 and t_index=0)
else balance
end
where address =
(select address from transaction where transfer_id=$1 and t_index=0)
But this doesn't set the consumed flag. The simplest way to do this is to make this a multi step transaction in your client application:
num_rows = txn.execute("UPDATE transfer SET consumed=true
WHERE id=$1 AND consumed=false", transfer_id)
if num_rows == 0: return
value, address = txn.query("SELECT value, address FROM transaction
WHERE transfer_id=$1 and t_index=0", transfer_id)
txn.execute("UPDATE balance_address SET balance = balance+$1
WHERE address = $2", value, address)
In PostgreSQL, I think you could get this into one big statement using common table expressions. However, CockroachDB 2.0 only supports a subset of CTEs, and I don't think it's possible to do this with a CTE in cockroach yet.

SSRS Subscription Schedule Started/Completed Events

I am pretty new to SSRS and I am trying to find a way to know when scheduled report is actually started on the server, when it has completed with success of failure and if it was canceled. As of now, I am using the ReportingService2010 class API to talk to the Report Server and the only way that it seems possible to me is to make something custom that checks the schedules and fire events at these times for the started events and to scan the folder where I'm going to save the report and when a new file is added, I know that the report has been successfully created, and maybe add a Timeout event after x time.
I don't think this is a really clean approach and I'm sure that you guys might have an easier answer because I'm sure that there must be a way to do it without manually scanning everything.
I used the ListJobs() method to access all the jobs that are currently running on the server but it doesn't seem to consider when a subscription is done, because, I only get results in the ListJobs() method when I manually click on "Run Now" for a specific report on the server.
Do you guys have any idea?
Thanks a lot,
Claude
There are few tables in 'ReportServer' database to provide you most of your information. e.g Subscriptions table has column as LastStatus, it gives how many subscriptions were processed and status of reports last run. e.g 'Done: 2 processed of 2 total; 0 errors' , 'Pending' ,
sample query would be like below, this is for getting a schedule but you can check and modify as you need.
Setup a new report with this query and schedule it as per your need to give you the status.
SELECT CAT.Name
,CAT.[Path] AS ReportPath
,SUB.LastRunTime
,SCH.NextRunTime
,CONVERT(VARCHAR(10), CONVERT(datetime, SCH.NextRunTime, 1), 101) As RunDate
,right(convert(varchar(32),SCH.NextRunTime,100),8) As RunTime
,SUB.[Description]
,SUB.EventType
,SUB.LastStatus
,SUB.ModifiedDate
,SCH.Name AS ScheduleName
FROM reportserver.dbo.Subscriptions AS SUB
INNER JOIN reportserver.dbo.Users AS USR
ON SUB.OwnerID = USR.UserID
INNER JOIN reportserver.dbo.[Catalog] AS CAT
ON SUB.Report_OID = CAT.ItemID
INNER JOIN reportserver.dbo.ReportSchedule AS RS
ON SUB.Report_OID = RS.ReportID
AND SUB.SubscriptionID = RS.SubscriptionID
INNER JOIN reportserver.dbo.Schedule AS SCH
ON RS.ScheduleID = SCH.ScheduleID
--Where CONVERT(VARCHAR(10), CONVERT(datetime, SCH.NextRunTime, 1), 101)
= CONVERT(VARCHAR(10), CONVERT(datetime, getDate()+1, 1), 101)
ORDER BY USR.UserName
,CAT.[Path];

Filtering SQL tables

I am trying to set up an sms appointment reminder for client appointments. I use the cms opemEMR. But there do not seem to be a appointment reminder function installed, and no extentions for that function. So I thought it will be possible to do that by filtering out the appointment from SQLi using PHP, and then set up a cron job.
I am new to php and mySQL, and I have been re-thinking how to do it so many times, that by head spins, so I hope some one can show me the right direction.
Here is how I think it can be done:
First I need to go to the calendar table that holds all the calendar events(1), and find the client appointments(2). Then I need to filter the appointments, that scheduled between 24 - 25 hours in advanced(3) (I will then tell the cron job to run every hour).
Then I will need to grab the client id(4) and the time of the appointment.
I will now have client ids on all client, I need to send reminders to.
Second I need to go to the patient data table(5), to grab the phone number(6) from the client ids(7) I just extracted.
I guess, I can then put this data in to another table, from where I can fetch it when running my sms-reminder.
This is a way, I believe would work, but I am no sure how to do it. Hope some one can show me.
Hope it makes sense and that the images help.
Reg.
Lars
Check this query:
SELECT e.pc_pid, e.pc_eventDate, e.pc_startTime,p.phone_cell FROM opememr_postcalendar_events e
LEFT JOIN patient_data p ON p.id = e.pc_pid
WHERE e.pc_Title = 'Office Visit' AND e.pc_eventDate BETWEEN DATE( DATE_SUB( NOW() , INTERVAL 1 DAY ) ) AND DATE ( NOW() )
ORDER BY e.pc_eventDate, e.pc_startTime;

Nested Cron jobs in Nodejs

I'm having a 'Tournament' sql table that contains start_time and end_time for my tournaments. I also have another table which has playerId and tournamentIds so I can tell which players playes in which tournament.
What I'm trying to do is to run a cron task to check my tournament table and see if tournament has ended so it can check players results from an external api. The problem is the external API has rate limit and I have to send my requestes every 1.5 sec.
What I tried to do is to write a cron job for every 10 seconds to check my tournament table (I couldn't come up with anyother solution rather than keep checking db):
cron.job("*/10 * * * * *", function(){
result = Query tournament table Where EndTime=<Now && EndTime+10second>=Now
if(result is not empty)
{
cron.job("*/1.5 * * * * *",function(){
send API requests for that userId
parse & store result in db
});
}
});
I don't feel right about this and it seems so buggy to me. Because the inner cron job might take longer than 10 seconds. Is there any good solution to do this. I'm using ExpressJS & MySQL.
The problem you are facing can be solved with event emitters. There is a very useful module node-schedule in npm which can help you in this scenario that you are telling. What you have to do is is to schedule a job to fire at the deadline of the project, that job will hit the 3rd party api and check for results.You an schedule a job like this
var schedule = require('node-schedule');
schedule.scheduleJob("jobName", "TimeToFire", function () {
//Put your api hit here.
//finally remove the schedule
if ("jobName" in schedule.scheduledJobs) {
schedule.scheduledJobs["jobName"].cancel();
delete schedule.scheduledJobs["jobName"];
}
})
Make sure you store all the jobs scheduled in the database also as a server crash will invalidate all the schedules that you have scheduled and will have to reschedule them again.

SSRS error handling

Is there a way to customize how SSRS reports its log? I would like SSRS to report subscription errors to a database, is there a way to do this?
Thank You
SSRS already logs the status of its subscriptions to the report server on the server that your instance of SSRS is running on. You could run the following query on your ReportServer and it will show you the last run status of the Subscription.
I've used this query in conjunction with an SSIS package to copy the report server database to create a report that sends out to various people telling them of the status of the subscriptions that exist on the report server
USE ReportServer
SELECT
CatalogParent.Name ParentName, --Folder names
Catalog.Name ReportName, --Actual rpt name
ReportCreatedByUsers.UserName ReportCreatedByUserName, --first deployed by
Catalog.CreationDate ReportCreationDate, --deployed on
ReportModifiedByUsers.UserName ReportModifiedByUserName, --last modification by
Catalog.ModifiedDate ReportModifiedDate,
CountExecution.CountStart TotalExecutions, --total number of executions since deployment
ExecutionLog.InstanceName LastExecutedInstanceName, --server excuted on
ExecutionLog.UserName LastExecutedUserName, --user name
ExecutionLog.Format LastExecutedFormat, --render format
ExecutionLog.TimeStart LastExecutedTimeStart, --start time
ExecutionLog.TimeEnd LastExecutedTimeEnd, --end time
-- These times need work, not always what you expect
ExecutionLog.TimeDataRetrieval LastExecutedTimeDataRetrieval,
ExecutionLog.TimeProcessing LastExecutedTimeProcessing,
ExecutionLog.TimeRendering LastExecutedTimeRendering,
-- end
ExecutionLog.Status LastExecutedStatus, --status of the report processing (not subscription)
ExecutionLog.ByteCount LastExecutedByteCount, -- bytes returned (just because i can)
ExecutionLog.[RowCount] LastExecutedRowCount,
SubscriptionOwner.UserName SubscriptionOwnerUserName, --subscription creator
SubscriptionModifiedByUsers.UserName SubscriptionModifiedByUserName, --subscription modifier
Subscriptions.ModifiedDate SubscriptionModifiedDate, --latest modification date
Subscriptions.Description SubscriptionDescription, --what the subscription does
Subscriptions.LastStatus SubscriptionLastStatus,
Subscriptions.LastRunTime SubscriptionLastRunTime --last time the subscription ran. this may be different to the last
-- execution time especially if report is set to cache
FROM
dbo.Catalog JOIN dbo.Catalog CatalogParent --rs catalog (all things deployed to rs)
ON Catalog.ParentID = CatalogParent.ItemID
JOIN dbo.Users ReportCreatedByUsers --all rs users
ON Catalog.CreatedByID = ReportCreatedByUsers.UserID
JOIN dbo.Users ReportModifiedByUsers
ON Catalog.ModifiedByID = ReportModifiedByUsers.UserID
LEFT JOIN (SELECT
ReportID,
MAX(TimeStart) LastTimeStart
FROM
dbo.ExecutionLog --self explanatory
GROUP BY
ReportID
) LatestExecution --gets the latest execution date rather than having a list longer than life
ON Catalog.ItemID = LatestExecution.ReportID
LEFT JOIN (SELECT
ReportID,
COUNT(TimeStart) CountStart
FROM
dbo.ExecutionLog
GROUP BY
ReportID
) CountExecution -- gets the number of executions (because we can)
ON Catalog.ItemID = CountExecution.ReportID
LEFT JOIN dbo.ExecutionLog
ON LatestExecution.ReportID = ExecutionLog.ReportID
AND LatestExecution.LastTimeStart = ExecutionLog.TimeStart
LEFT JOIN dbo.Subscriptions --subscription details
ON Catalog.ItemID = Subscriptions.Report_OID
LEFT JOIN dbo.Users SubscriptionOwner --user info
ON Subscriptions.OwnerID = SubscriptionOwner.UserID
LEFT JOIN dbo.Users SubscriptionModifiedByUsers --user info
ON Subscriptions.OwnerID = SubscriptionModifiedByUsers.UserID
ORDER BY
CatalogParent.Name,
Catalog.Name
Logging and reporting on the stack trace as in the LogFiles on the server is a little less straightforward!
SSRS have a default logging mechanism on SQL server instance being used with SSRS report. you can find the log file on the following path.
C:\Program Files\Microsoft SQL Server\MSRS11.MSSQLSERVER\Reporting Services\LogFiles
Top most file have all the reporting server logs, open that file and navigate to the end to view most recent logs.