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.
Related
I want to create a procedure that constantly checks and compares row counts between source and target table. If source table has a higher row count then I want to execute a SQL Server Agent job and my procedure should wait till that job finishes.
For Example:
create proc 'XYZ'
case when a.count(*) > b.count(*) then sp_start_job 'SSIS_package_ABC'
wait for 'package execution completion'
I would really appreciate it if someone could point me in the right direction as I am new to SQL Server Agent.
Use IF statements instead of CASE:
DECLARE #SRC_TABLE_CNT INT,
#DEST_TABLE_CNT INT
SELECT #SRC_TABLE_CNT = COUNT(*) FROM SOURCE_TABLE
SELECT #DEST_TABLE_CNT = COUNT(*) FROM DEST_TABLE
IF #SRC_TABLE_CNT > #DEST_TABLE_CNT
BEGIN
sp_start_job 'SSIS_package_ABC'
END
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 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.
First, here is the code for sp_GetWorkQByUserName:
ALTER PROCEDURE [dbo].[sp_GetWorkQByUserName]
( #UserName varchar(50),
#StartDate datetime,
#EndDate datetime )
AS
BEGIN
SET NOCOUNT ON;
SELECT DISTINCT SpotId FROM tblSpotCount WHERE StoreNum = EXECUTE sp_GetUserLocationCodes(#UserName)
ORDER BY SpotDt ASC
END
I know my SELECT DISTINCT statement is wrong, but I wrote it like that to help show what I'm trying to do. I want to run this stored procedure based on the results from the sp_GetUserLocationCodes with a parameter of #UserName.
From what I can tell, my problem lies in how I'm calling sp_GetUserLocationCodes.
Question: how can I run a SELECT DISTINCT query on tblSpotCount.SpotId based on the results from the sp_GetUserLocationCodes stored procedure?
You cannot use a stored procedure directly in a query. You can, however, insert the results of a stored procedure into a temporary table and use that in your query:
CREATE TABLE #storeLocations
(
-- appropriate column names and data types go here
)
INSERT INTO #storeLocations (put column list here)
EXECUTE sp_GetUserLocationCodes(#UserName)
SELECT DISTINCT SpotId
FROM tblSpotCount
WHERE EXISTS (SELECT 1
FROM #storeLocations
WHERE #storeLocations.StoreNum = tblSpotCount.StoreNum)
ORDER BY SpotDt ASC
DROP TABLE #storeLocations
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.