Automatically update a column with a special date in SQL Server - sql

I have a table with 2 columns:
ExpireDate(DateTime)
IsExpired(Bit).
Is there any way that I can check automatically if ExpireDate >= Today Date and change the IsExpired column from false to true?
In fact, I would this process happened for each record in ExpireDate and I don't want check all of record manually to found what recode is expire then change IsExpired column.

You can change the IsExpired field with an update query like this:
UPDATE table SET IsExpired = 1 WHERE ExpireDate >= GetDate()
And if you want it to happen automatically you can schedule a job doing this using the SQL Server Agent.

Try following :
update yourtablename
set isexpired = 1
where ExpireDate >= convert(date,getdate())

If you want this to happen automatically, then use a view or computed column. You can add a computed column like this:
alter table YourTable
add column isexpired as (case when ExpireDate >= getdate() then 1 else 0 end);
(You might have to drop the column first.)
The advantage of a computed column is that it never gets out of date.

Related

Add column to existing table set default to sysdate for existing records and tomorrows date for new entries

Hi I am learning SQL while I found below task,
Insert a new column StartDate in existing table and for the existing records should have sysdate and for new entries should have tomorrow's date.
until now I did
ALTER TABLE test
ADD StartDate DATETIME NOT NULL DEFAULT (GETDATE());
from here I unable to go forward i am thinking the task itself is not correct am i thinking correct or can we perform this task pls anyone help me out.
First read Sean’s comment on making the column NULLABLE. Then, you'd change your command to:
The default should be dateadd(day,1,getdate()). This would work for future inserts where you don't specify a value on insert.
ALTER TABLE test
ADD StartDate DATETIME NULL DEFAULT (DATEADD(DAY,1,GETDATE()));
For the other rows, you simply need to update then once you have made this table change.
update table test
set StartDate = getdate()
where StartDate is null --which is every row that wasn't inserted after the change
Then, alter the column to make it NOT NULL
ALTER TABLE test
ALTER COLUMN StartDate DATETIME NOT NULL DEFAULT (DATEADD(DAY,1,GETDATE()));
Try this:
ADD StartDate2 DATETIME NOT NULL DEFAULT (DATEADD(DAY, 1,GETDATE()));

How to change a field data after time t in a table?

Is it possible to change the data in table automatically after time i.
Say time i = 10 sec.
Table t, has column x1,x2,x3.
x3 is boolean as datatype. x3'll be false by
Now suppose I changed the value in t.x3 (any row) to True then after 10 sec it should change itself to False.
Is it possible.? By some trigger or cursor or procedure or something?
Alteast need a keyword to google it.
Thank You!
You can do this without a trigger. Just use a computed column.
For instance:
create table t (dte datetime,
flag as (case when dte < dateadd(second, -10, getdate()) then 0 else 1
end)
);
This is a computed column. It will recalculate when it is queried, doing the calculation you are asking for.
This scenario you are asking for looks like an anti-pattern. Exists a command to wait for random amount of time ( WAITFOR DELAY '00:00:02'; ) but, usually, is not a good idea to use it:
Caution+
Including WAITFOR will slow the completion of the SQL Server process and can result in a timeout message in the application. If necessary, adjust the timeout setting for the connection at the application level.
In my opinion, the easy way is to create a view over your table and calculate the field on the fly:
CREATE TABLE t ( PrimaryKey ....,
x3 bit,
t datetime default gettime(),
);
CREATE VIEW v as
SELECT PrimaryKey,
(CASE WHEN x3 = 1 and datediff(second, t, getdate()) > 10
THEN 1
ELSE 0
END ) as x3 --<-- lets supose this is your field.
FROM t;
Then, you can select from view to check for your calculate field:
SELECT x3 FROM v; --<-- select from v instead from t.
You can use a trigger to keep t field up to date on change x3:
CREATE TRIGGER updateModified
ON dbo.t
AFTER UPDATE
AS
UPDATE dbo.t
SET t = getdate()
FROM Inserted i
WHERE dbo.t.PrimaryKey = i.PrimaryKey
You can use a trigger to automatically update the values after something has changed on the table. But this change will be affected within milliseconds as the trigger executes straight after the update/insert/delete.
The second method you can do is to create a scheduled Database job which will run every 10 seconds (In this case) or any specific interval, which will make the updates in the required columns.
Refer this Article for more information on scheduling the DB Jobs

Display Now date and Time in SQl table column

I want to be able to have todays date and time now in a table column
If my table is say Table1, basically it should display the time and date when
SELECT * FROM Table1 is run.
I've tried the following but they just show the time from the moment in time I assign the value to column
ALTER TABLE Table1
ADD TodaysDate DateTime NOT NULL DEFAULT GETDATE()
and
ALTER TABLE Table1
ADD TodaysDate DateTime
UPDATE Table1
SET TodaysDate = GETDATE()
Hope this is clear. any help is appreciated.
Thanks
In SQL Server you can use a computed column:
alter table table1 add TodaysDate as (cast(getdate() as date));
(use just getdate() for the date and time)
This adds a "virtual" column that gets calculated every time it is referenced. The use of such a thing is unclear. Well, I could imagine that if you are exporting the data to a file or another application, then it could have some use for this to be built-in.
I hope this clarifies your requirement.
The SQL Server columns with default values stores the values inside the table. When you select the values from table, the stored date time will be displayed.
There are 2 options I see without adding the column to the table itself.
You can use SELECT *, GETDATE() as TodaysDate FROM Table1
You can create a view on top of Table 1 with additional column like
CREATE VIEW vw_Table1
AS
SELECT *, GETDATE() as TodaysDate FROM dbo.Table1
then you can query the view like you mentioned (without column list)
SELECT * FROM vw_Table1
This will give you the date and time from the moment of the execution of the query.

Using CASE Statement in a table

Is it possible to have a column in a table (not from view)(SQL SERVER 2008) to change according to a value in another column i.e. if I have a column called "DUEDATE" can I have a column called "STATUS" that will change the status to "Now Due" if the "DUEDATE" is > GetDate()? If so how do you add that to a table?
You can alter the table and add a computed column:
ALTER TABLE dbo.TheTable
ADD Status AS CASE WHEN ...
You can't persist it, because it's non-deterministic, so don't add PERSISTED or try to put an index on it.
From an indexing perspective, don't try to query it using WHERE Status = 'whatever', because it will have to consider every row in the table. Instead, use an index on DueDate and WHERE DueDate <= GETDATE()
Yes, you can create a computed column:
CREATE TABLE [dbo].[SampleTable](
[DueDate] [date] NULL,
[ComputedValue] AS (CASE WHEN [Duedate] > GETDATE() THEN 'Now Due' ELSE '' END)
) ON [PRIMARY]
As this is a non-deterministic column (because of the value of GETDATE() that is different every time you use the table), adding it to the table doesn't give you much benefit over returning the same in a select query.

SQL - how to check table for new data?

I need to create a stored procedure that upon exceution checks if any new rows have been added to a table within the past 12 hours. If not, an warning email must be sent to a recipient.
I have the procedures for sending the email, but the problem is the query itself. I imagine I'd have to make an sql command that uses current date and compares that to the dates in the rows. But I'm a complete beginner in SQL so I can't even use the right words to find anything on google.
Short version:
Using MS SQL Server 2005, how can I check against the dates, then return a result based on whether new rows were created within the last 12 hours, and use that result to decide whether or not to send email?
Something like this should do what you wish.
Select ID
from TableName
where CreatedDate >= dateadd(hour,-12,getDate())
Hope this is clear but please feel free to pose further questions.
Cheers, John
Say your date field in the table is 'CreateDate' and it's of type DateTime.
Your time to compare with is: GETDATE()
(which returns date + time)
To get the datetime value of 12 hours before that, is done using DATEADD:
DATEADD(hour, -12, GETDATE())
so if we want the # of rows added in the last 12 hours, we'll do:
SELECT COUNT(*)
FROM Table
WHERE CreateDate >= DATEADD(hour, -12, GETDATE())
in your proc, you've to store the result of this query into a variable and check if it's > 0, so:
DECLARE #amount int
SELECT #amount=COUNT(*)
FROM Table
WHERE CreateDate >= DATEADD(hour, -12, GETDATE())
and then you'll check the #amount variable if it's > 0.
You could use a trigger, this link has several examples: http://msdn.microsoft.com/en-us/library/aa258254(SQL.80).aspx
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'reminder' AND type = 'TR')
DROP TRIGGER reminder
GO
CREATE TRIGGER reminder
ON titles
FOR INSERT, UPDATE, DELETE
AS
EXEC master..xp_sendmail 'MaryM',
'Don''t forget to print a report for the distributors.'
GO
If you do not want something for each insert/update, you could copy data to a another table then examine that table every 12 hours, report on the rows in it, then delete them...
assuming you have on this table :
- either a unique id autoincrementing
- either a created_timestamp field containing the timestamp of creation of the row
-> have a new table
reported_rows
- report_timestamp
- last_id_seen
(OR)
- last_timestamp_seen
fill the reported row each time you send your email with the actual value
and before sending the email, check with the previous values, so you know what rows have been added
If the table has an identity field, you could also save the max value (as a bookmark) and next time check if there are any rows with an ID greater than your saved bookmark. May be faster if the key is the clustered key.