I'm a novice at SQL server and I have a task to create a trigger that will insert/update a customer's status to 'Blocked' in a payment is overdue.
How could I check to say something like the following within a trigger?
if getdate() > dateDue
then update status = 'Blocked'
end if
Many thanks for you help in advance
Here's an implementation of Martin's suggestion to create a non-persisted computed column:
ALTER TABLE dbo.YourTable
ADD Status AS CASE WHEN DueDate < GETDATE() THEN 'Blocked' ELSE 'Not Blocked' END
I don't have time to really test this, so there might be some problems / syntax issues, but here's something that should give you an idea how to go about it. Basically, your trigger should fire whenever the value of "dateDue" is changed. It should iterate through the "inserted" values in case more than one record was updated, and for each record in "inserted", if the new "dateDue" value is > the current time, you update that record and set the status to 'Blocked'.
CREATE TRIGGER myTriggerName
ON myTable
AFTER INSERT, UPDATE
AS
IF UPDATE(dateDue)
BEGIN
DECLARE #currPk INT
DECLARE #currDateDue DATETIME
DECLARE #today DATETIME
DECLARE inserted_Cursor CURSOR FOR
SELECT myTableID, dateDue, GETDATE() FROM Inserted
OPEN inserted_Cursor;
FETCH NEXT FROM inserted_Cursor INTO #currPk, #currDateDue, #today
WHILE ##FETCH_STATUS = 0
BEGIN
IF(#currDateDue < #today)
UPDATE myTable SET status = 'Blocked' WHERE myTableID = #currPk
FETCH NEXT FROM inserted_Cursor INTO #currPk, #currDateDue, #today
END;
CLOSE inserted_Cursor;
DEALLOCATE inserted_Cursor;
END;
If you want to have this status updated when dueDate becomes < today, as opposed to only updating it when the dueDate for the record is modified, you should schedule a stored procedure via SQL Sever Agent and have it run a simple update to set the statuses for any records where dueDate < today. You can run this nightly, or every hour, or whatever you need.
If you don't want to run Agent, you could do it with a Windows service that you write code for (more of a pain to set up), or even a batch file that runs from a Windows Task, but obviously Agent is the most convenient way to do this.
Related
I'm creating a table and setting up a trigger to insert/update field_3 using field_1 and 2. See my example below.
ID | Start_Date | End_Date | Period |
1 3/10/17 3/20/17 10
2 2/05/17 3/10/17 5
Trigger
ALTER TRIGGER [dbo].[tr_insert_Period]
ON [dbo].[MEDICAL_EXCUSE]
for update
AS
BEGIN
SET NOCOUNT ON;
declare #Start_Date Datetime
declare #End_Date Datetime
declare #Period Float
set #Start_Date = ( select me_start_date from inserted)
set #End_Date = ( select ME_End_Date from inserted)
set #Period = ( select Period from inserted)
update MEDICAL_EXCUSE
set #Period = DATEDIFF(day,#Start_Date , #End_Date)
END
it won't trigger just work if you execute Manually.
Any help Much Appreciated.
Don't use a trigger. Just use a computed column. I think this is what you want:
alter table KOPS_MEDICAL_EXCUSE
add period as (DATEDIFF(day, me_start_date, me_end_date));
Note that datediff() returns an integer, so there is no reason to declare anything as a float.
With a computed field, the value is usually calculated when you query the table. You can materialize the value if you want using the PERSISTED keyword.
Several issues I see with your trigger. First you can never assume only one record is going to be updated ever. Enterprise databases (typically the only kind complex enough to need triggers) often are accessed outside the user application and a large insert might appear.
Next, you want to get the records from an insert, so it needs to be an insert trigger. And finally you are updating the value of the variable #period instead of the field Period in your table.
Try this:
ALTER TRIGGER [dbo].[tr_insert_Period]
ON [dbo].[MEDICAL_EXCUSE]
for insert
AS
BEGIN
UPDATE ME
SET Period = DATEDIFF(day,i.Start_Date , i.End_Date)
FROM MEDICAL_EXCUSE ME
JOIN Inserted i on i.id = me.id
END
You might also want this to work for updates as well, so then make it:
FOR Insert, update
I'm having a problem with adding a date and time when a record added into my database. The problem is because I have clients from different time zones. What I thought of doing is I'm allowing the users to change the time zone and I save it in a table tbl_timezone which keeps UserIDReg (for example 1) and timezone_time (for example +2)
What I was thinking is while I try to add the records into the database to search for that user in tbl_timezone and add the timezone_time into the system current time which is always UTC+00:00.
Appreciate helping me solve this problem.
Here is the stored procedure for adding the record
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Cp_Recivers_Insert]
#SmsR_SmsID bigint ,
#SmsR_UserIDReg int
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION SmsR
IF #SmsR_DateReg IS NULL
BEGIN
SET #SmsR_DateReg = (SELECT CAST(GETDATE() AS datetime))
END
INSERT INTO Prj_SmsRecivers (SmsR_SmsID, SmsR_DateReg, SmsR_UserIDReg)
VALUES (#SmsR_SmsID, #SmsR_DateReg, #SmsR_UserIDReg)
SELECT ##IDENTITY As SmsR_ID
COMMIT TRANSACTION SmsR
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION SmsR
END CATCH
END
I have a problem with the next TRIGGER in SQL server 2008:
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Order int,
#Payment varchar(15)
select #order=OrderID,#payment=PaymentType from inserted
IF #Payment='paypal'
begin
exec PaypalTransactionsUpdate #OrderID=#Order
end
ELSE
begin
Return
end
END
I can't understand why does not work the select from the inserted table. If I use like:
select TOP 1 #order=OrderID,#payment=PaymentType from TABLENAME where PaymentType='Paypal' order by OrderID desc.
It works perfectly, anybody can help me? I want to use the row table inserted to prevent data errors becuase the second statement is no secure, maybe the top one already changes when the trigger runs.
I was using the top1 select this weekend and was working for some orders and for some one don't for no reason. I saw this morning that the row that I want to synchronize , the trigger do it in the next insert, this means, when Paypal order comes stay there without synchronize until the next order comes and rerun the trigger. I am using the after insert modify method and can't understand why this happens. Any ideas?
I will appreciate as well if someone give me a clue how to test Trigger or see the error log of them.
I have a table with a date field, and I want to execute a certain query when that date reaches the current date. Is there any way to do that on Sql Server?
One way or say good way is making a Sql - job and second is trigger. But trigger is not suitable and also not advisable to use.
Sqljob is automated process, just give date-time with day and it will executed automatically. In that you call the sp, where first check the date and then process as you want.
First create a job, please check the link
http://www.databasedesign-resource.com/sql-server-jobs.html
http://forums.asp.net/p/1364020/2826971.aspx
Now create a sp which executed by job like (This is sample example)..
create procedure spname()
as
begin
declare #currentdate datetime = getdate()
declare #tempdateToCheck datetime = (select datecolumn from tablename where ....give condition if any )
if(#tempdateToCheck >= #currentdate)
begin
--execute statement you want like
insert tablename .... --insert statement
update tablename.... --update statement
declare #tempvariable1 int --anydatatype you define and any no. of variable, you want.
select #tempvariable1 = columnname from tablename
update tablename1 set columname = #tempvariable1 where condition
end
end
You can create a sql server agent job in order to check the date column everyday and if reached then execute query.
I want a SQL trigger to fire when a table is updated. I have a table called SimActivation and a stored procedure called spUpdateMnpDate that takes two parameters, msisdn(varchar) and date(datetime).
When the SimActivation table is updated I want to call the procedure with the new values.
Here is what I got at the moment, after changing it back and forth:
USE StoreSale;
GO
CREATE TRIGGER dbo.tSyncMnpDate
ON [dbo].[SimActivation]
AFTER UPDATE
AS
DECLARE #date datetime
DECLARE #msisdn varchar(10)
SET #date = (select ProcessDate from inserted)
SET #msisdn = (select Msisdn from inserted)
EXEC [spUpdateMnpDate]
#msisdn, #date;
GO
Can anyone point me in the right direction?
Thanks :)
The problem you have is that a trigger will fire when one or more rows have been updated. At the moment you are assuming your trigger will fire for each row, which is not the case in SQL Server.
If the stored procedure you are trying to call is fairly simple I'd pull the code out of there and in to the trigger. But remember you are working with sets of changed rows (even if the change is to only one row) so you have to write your SQL accordingly.
EDIT: I assume your procedure is updating a date where the PK is equal to #msisdn, if so you can do this in your trigger:
UPDATE Your_Table
SET Your_Table.ProcessDate = inserted.ProcessDate
FROM Your_table INNER JOIN inerted ON Your_Table.Msisdn = inserted.Msisdn
Joining the tables ensures it will work for one or many updated rows.