I am trying to create an alert to be sent daily. The condition is to display all the Return Orders not completed.
I am expecting it to be sent later today, then just in case there were items on those data that are still not completed by tomorrow, then it will sent out again.
Is there a need to query that condition? let's say
SELECT SalesOrderNo, SalesOrderDetailID, CustomerNo, ItemNo, DueDate
, Completed, Qty, UDCode, CustomerPO
FROM dbo._EventAlertReturns
WHERE GETDATE() is today?
What is the best way to do that?
At the moment, your query is adequate on its own, you don't need that WHERE clause - but you cannot set up an automated process using a mere SELECT statement.
As Jon Vote said, to do something like this you need a SQL Server Scheduled Job. With a scheduling agent you could create a scheduled package to execute in the evening which emails you the results of your query.
For additional granularity you can look into SQL Server Data Tools to more-easily create tasks and settings for your automated packages.
Related
Let's say I have a table with a date column; can I attach some sort of "watcher" that can take action if the date gets smaller than getdate()? Note that the date is larger than getdate() at the time of insertion.
Are there any tools that I might be unaware of in SQL Server 2008/2012?
Or would the best option be to poll the data from another application?
Edit: Note that there is no insertion/update taking place.
You could set up a SQL Job which runs periodically and executes a stored procedure which can then handle the logic around past dates.
https://msdn.microsoft.com/en-gb/library/ms187910.aspx
For example a SQL Job could be set up to run once daily to find out user's birthdays and send out an automated email.
In your case a job could be set up every minute (if required) which detects past dates and does something with those records. I would suggest adding some kind of flag to each record so that it isn't actioned the next time the job runs.
Alternatively if you have a lot of servers and databases, you could centralise your job scheduling using a third-party tool such as ActiveBatch.
I am writing a web application. In its database there is a table that keeps some due dates. Another table has two columns: name and state. I want the state column to be automatically updated when any of those due dates arrives (the updated value is calculated according to some logic in my program).
How can I implement this functionality? Is it common to run another program (independent of my web application) on the server machine to check the database for due dates and update the table or there are other ways?
Although some databases support scheduled tasks, most DBAs use cron to schedule a task that does the work.
I suggest you do the same.
(Thanks to catcall for his comment)
DELIMITER $$
CREATE EVENT 'DBNAME'.'EVENTNAME'
ON SCHEDULE
EVERY 1 DAY
ON COMPLETION PRESERVE
ENABLE
DO
BEGIN
/*sql statements*/
UPDATE tableName SET state = 'newState' where NOW() = (SELECT * FROM tableWithDates);
END
DELIMITER ;
this is a code that creates an event in MySql. you can update data in your tables using Mysql events. this event runs every 1 day and then executes the sql query. MySql events runs also on the background.
I'm designing a library management database schema, let's say there is a table "Borrow"
Borrow
id
user_id
book_id
borrow_date
due_date
isExpired
expired_day (number of days after the book is expired)
fine
Can the SQL Trigger implement the following circumstances?
1.Compare the due_date with Today, if it's same-->send email-->mark isExpired to true
2.If isExpired is marked to true-->compare the difference between today and due_date, and update expired_day--->update fine (expired_days * 5)
A trigger only fires when something happens on the table or row. It won't fire continuously (or daily). If nothing happens to the table then your trigger will never fire so your checks can't be done.
So, the trigger you describe would work when you first insert a record into the row, but there's no automatic way with a trigger for it to fire after the due date period to check for the expiry and fine.
You would most likely need to setup a stored procedure that contained your code and find a way to run that on scheduled basis.
The following link goes over how to set that up:
Scheduled run of stored procedure on SQL server
Since you want to check all the records of the library daily and want them to be updated accordingly, it is better to make a daily job and schedule an agent and set a particular time so that this daily job would be executed everyday automatically.
pls Note : You should keep in mind to choose that time when you feel your application would be least used during the entire day.
Creation of Agent : http://msdn.microsoft.com/en-us/library/ms181153(v=sql.105).aspx
I am currently in the process of revamping my company's management system to run a little more lean in terms of network traffic. Right now I'm trying to figure out an effective way to query only the records that have been modified (by any user) since the last time I asked.
When the application starts it loads the job information and caches it locally like the following: SELECT * FROM jobs.
I am writing out the date/time a record was modified ala UPDATE jobs SET Widgets=#Widgets, LastModified=GetDate() WHERE JobID=#JobID.
When any user requests the list of jobs I query all records that have been modified since the last time I requested the list like the following: SELECT * FROM jobs WHERE LastModified>=#LastRequested and store the date/time of the request to pass in as #LastRequest when the user asks again. In theory this will return only the records that have been modified since the last request.
The issue I'm running into is when the user's date/time is not quite in sync with the server's date/time and also of server load when querying an un-indexed date/time column. Is there a more effective system then querying date/time information?
I don't know that I would rely on Date-Time since it is external to SQL Server.
If you have an Identity column, I would use that column in a table UserId, LastQueryDateTime, LastIdRetrieved
Every time you query the base table, insert new row for user (or update if exists) the max id into this table. Also, the query should read the row from this table to get the LastIdRetrieved and use that in the where clause.
All this could be eliminated if all of your code chooses to insert GetDate() from SQL Server instead of from the client machines, but that task is pretty labor intensive.
The easiest solution seems to settle on one time as leading.
One way would be to settle on the server time. After updating the row, store the value returned by select LastModified where JobID = #JobID on the client side. That way, the client can effectively query using only the server time as reference.
Use an update sequence number (USN) much like Active Directory and DNS use to keep track of the objects that have changed since their last replication. Pick a number to start with, and each time a record in the Jobs table is inserted or modified, write the most recent USN. Keep track of the USN when the last Select query was executed, and you then always know what records were altered since the last query. For example...
Set LastQryUSN = 100
Update Jobs Set USN=101, ...
Update Jobs Set USN=102, ...
Insert Jobs (USN, ...) Values (103, ...)
Select * From Jobs Where USN > LastQryUSN
Set LastQryUSN = 103
Update Jobs Set USN=104
Insert Jobs (USN, ...) Values (105, ...)
Select * From Jobs Where USN > LastQryUSN
Set LastQryUSN = 105
... and so on
When you get the Jobs, get the server time too:
DECLARE #now DATETIME = GETUTCDATE();
SELECT #now AS [ServerTime], * FROM Jobs WHERE Modified >= #LastModified;
First time you pass in a minimum date as #LastModified. On each subsequent call, you pass in the ServerTime returned last call. This way the client time is taken out of the equation.
The answer to the server load is, I hope, obvious: add an index on Modified column.
And one more adice: never use local time, not even on server. Always use UTC times, and store UTC time in Modified. As it is right now, your program is completely screwed two times a year, when the daylight savings time changes are set in or when they are removed.
Current SQL Server has change tracking you can use for exactly that. Just enable change tracking on the tables you want to track.
I have a table, tblClient, which stored a client's date of birth in a field of type datetime, DOB.
The goal here is that, when a client reaches 65 years old (need to be calculated thru DOB), I need to insert a new record into another table.
But since the age of a client does not change due to a database transaction (INSERT,UPDATE,DELETE), trigger is out of question.
What would be a good idea to montior such changes?
create a sql agent job that runs daily or hourly that will do this calculation with T-SQL and then if someone reaches 65 it will do the insert
Keep it as self-contained to SQL Server as possible - a SQL Server Agent job that periodically executes a stored procedure should do nicely.
A scheduled task or SQL Server maintenance plan that runs a stored procedure as often as required, updating the required rows.
What about a nightly job using SSIS with a stored procedure that checks and if it happens that they are 65 it enters a new row in the table?
you can create a SQL Server Agent Job within the database using SQL Server Management Studio for this:
http://www.databasedesign-resource.com/sql-server-jobs.html
Set up a daily job to EXEC BirthdayProcessingProcedure or whatever you want to name it.
As long as the database is up and running, the JOB will run according to the schedule you set up (from within the database).
I'm going to propose another approach - run something every time a DOB is updated (or added) that calculates the period from now until the first person reaches 65. Then (re-)schedule a job to run at that time.
Also, I can't believe you need to insert that row the second they reach 65, so a once-a-day procedure that calculates today's new 65year olds would seem good enough?
How about a new field that is age65 date. Calculate it once on record insert, then you can query to your hearts content on this field. You will need to do this is a trigger (and account for updates, they are rare for DOB fields but possible when they are mistyped.) Now that I think about it some, a calculted filed will probably work instead of a trigger.
Then run a daily job to catch anyone who turned 65 since the last time the job was run successfully. Make sure to handle this so that if the job fails one day, the people from that daty are picked up the next run.
The reason why I suggest this is that calculating the age of every person inyour database every day is such a waste of resources for a calculation that really only needs to be done once. Ok not a big deal when you have 100 people, big problem when you have a million. Doindthis kindof calc on a million records to identify the three you need is painful. Doing it once on data entry, not so bad.