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.
Related
I'm going to create a trigger for update. Purpose of this trigger is that If muadurum column is changed , take the old value of mua_tarih in table fkayitlar and insert to another table mua_tarihleri.
My code block like;
ALTER TRIGGER [dbo].[trgr_fkayit_update]
ON [dbo].[fkayitlar]
AFTER UPDATE
AS
DECLARE #mua_durum_once NVARCHAR(10)
DECLARE #mua_durum_sonra NVARCHAR(10)
DECLARE #mua_tarih_once DATE
DECLARE #mua_yapan_once NVARCHAR(25)
DECLARE #kisi_id INT
Take the old value;
SELECT
#kisi_id=kayitid,
#mua_durum_once=muayenedurum,
#mua_tarih_once=muayenetarih,
#mua_yapan_once=mua_yapan
FROM deleted
Take the new value;
SELECT #mua_durum_sonra=muayenedurum FROM inserted
Check if value is changed ; if changed, Insert #mua_tarih to table mua_tarihleri with #kisi_id and #mua_yapan_once
IF #mua_durum_once='OLDU'
AND #mua_durum_sonra='OLMADI'
AND #mua_tarih_once IS NOT NULL
BEGIN
INSERT INTO mua_tarihleri(kayitid,mua_tarihi,mua_yapan)
VALUES(#kisi_id,#mua_tarih_once,#mua_yapan_once)
END
My problem is When I update more than one row in table fkayitlar,Trigger is working, but I see only one inserted row in table mua_tarihleri (only working once). I need to see more than one.(should be working more than once) Are not Triggers working on more than one process? or How can I solve this my problem?
The trigger only occurs once when the table is updated, no matter how many rows are updated. Therefore, you have to write your trigger body to operate on a set of rows, not a single row as you have done.
Should be something like:
ALTER TRIGGER [dbo].[trgr_fkayit_update]
ON [dbo].[fkayitlar]
AFTER UPDATE
AS
INSERT INTO mua_tarihleri(kayitid,mua_tarihi,mua_yapan)
SELECT deleted.kayitid, deleted.muayenedurum, deleted.muayenetarih, deleted.mua_yapan
FROM deleted
JOIN inserted ON deleted.kayitid = inserted.kayitid
WHERE deleted.muayenedurum='OLDU'
AND inserted.muayenedurum='OLMADI'
AND muayenetarih IS NOT NULL
I wrote a simple stored procedure which is supposed to update an existing table a based on another table b that is continually having values added.
I want the stored procedure to run every time a value is added to b.
I wrote a simple trigger that I think should work but it is not working. The trigger just executes the stored procedure every time there is an insert or update in b.
Here is what the trigger looks like:
CREATE TRIGGER [dbo].[TriggerTest]
ON [dbo].[BELL_DPRA2_locates_fact]
AFTER UPDATE, INSERT
AS
BEGIN
EXECUTE dbo.Test
END
If I run the procedure separately, it works fine. It updates the first table.
But If I leave it waiting for the trigger to act, nothing happens. Table b in the meantime is having data stream in every second. Please help me find the what the problem is.
Here is the stored procedure:
CREATE PROCEDURE [dbo].[Test]
AS
BEGIN
DECLARE #CurDate DATE
SET #CurDate = CAST((SELECT GETDATE()) AS DATE);
MERGE INTO dbo.DPRA2_Export T
USING (SELECT
CAST(risk_date AS DATE) as "Dated",
COUNT(risk_score) AS "Risk2"
FROM
dbo.BELL_DPRA2_locates_fact
WHERE
Risk_Score = 2
AND CAST(Risk_Date AS DATE) = #CurDate
GROUP BY
CAST(risk_date AS DATE)) S ON T.Risk_Date_Day = S.Dated
WHEN MATCHED THEN
UPDATE SET T.Risk2 = S.Risk2
WHEN NOT MATCHED THEN
INSERT (Risk_Date_Day, Risk2)
VALUES (#CurDate, S.Risk2);
END
I have a master table , say mast_tbl, where every change on this table goes as a different entry into hst_mast_tbl. There is col in both the tables which talks about status change. Now if I want to track the number of records for which only the status has changed in the past 10 days, how can I achieve it in a simplest way?
To use lag function, sometimes there might be more column getting updated in master table so more than 1 record in my history table. So how can I achieve the same.
Thanks in advance.
Have you tried using triggers? If you are using SQL Server this might help you.
You can utilize the trigger by using FOR UPDATE when certain column is edited on your table you could say
CREATE TRIGGER [dbo].[trg_update] ON [dbo].[tbl_trans]
WITH EXECUTE AS CALLER
FOR UPDATE
AS
BEGIN
DECLARE #transaction VARCHAR(15)
DECLARE #action VARCHAR(10)
DECLARE #ref_id INT
DECLARE #trail_date DATETIME
SELECT
#transaction = '<your table here>',
#action = 'Update',
#ref_id = i.trans_id,
#trail_date = GETDATE()
FROM INSERTED i
INSERT INTO tbl_auditTrail (audit_trans,action,ref_id,trail_date)
VALUES (#transaction,#action,#ref_id,#trail_date)
END
GO
something like this.
I'm working on a small database in SQL Server 2008 to track employee changes. I'm having trouble with an Insert Trigger at the moment. What I want to happen, is that when a "Record" is inserted into the Record table, it finds the previous open record (i.e. one without an end date) for that Employee (EmpID), if there is one, and updates it with an EndDate - which will be calculated as the day before the inserted StartDate. Here is what I have tried, to no success:
CREATE TRIGGER [dbo].[trgInsertRecord] ON [dbo].[Record]
FOR INSERT
AS
declare #EmpID int;
declare #StartDate date;
declare #EndDate date;
select #EmpID=i.EmpID from inserted i;
select #StartDate=i.RealStart from inserted i;
set #EndDate=DATEADD(DAY,-1,#StartDate)
UPDATE Record
SET RealEnd=#EndDate
WHERE EmpID=#EmpID AND RealEnd=NULL;
Can somebody please help me understand my mistake?
Assuming only a single row exists for a given EmpID and NULL RealEnd, you can join to the inserted table for the update operation like the example below. The best practice is to code triggers as to handle multiple rows updated by a single statement so you should avoid local scalar subqueries in triggers.
CREATE TRIGGER [dbo].[trgInsertRecord] ON [dbo].[Record]
FOR INSERT
AS
UPDATE r
SET RealEnd = DATEADD(DAY, -1, i.RealStart)
FROM Record AS r
JOIN inserted AS i ON
r.EmpID=i.EmpID
AND RealEnd IS NULL;
I need a SQL trigger that would zero pad a cell whenever its inserted or updated. Was curious if its best practice to append two strings together like I'm doing in the update command. Is this be best way to do it?
CREATE TRIGGER PadColumnTenCharsInserted ON Table
AFTER INSERT
AS
DECLARE
#pad_characters VARCHAR(10),
#target_column NVARCHAR(255)
SET #pad_characters = '0000000000'
SET #target_column = 'IndexField1'
IF UPDATE(IndexField1)
BEGIN
UPDATE Table
SET IndexField1 = RIGHT(#pad_characters + IndexField1, 10)
END
GO
Your padding code looks fine.
Instead of updating every row in the table like this:
UPDATE Table
update just the row that triggered the trigger:
UPDATE updated
Also, you've still got some extraneous code -- everything involving #target_column. And it looks like you're not sure if this is an INSERT trigger or an UPDATE trigger. I see AFTER INSERT and IF UPDATE.
Two questions:
What are you doing with #target_column? You declare it and set it with a column name, but then you never use it. If you intend to use the variable in your subsequent SQL statements, you may need to wrap the statements in an EXECUTE() or use sp_executesql().
The syntax "UPDATE Table..." is OK for your update statement assuming that "Table" is the name of the table you are updating. What seems to be missing is a filter of some kind. Or did you really intend for that column to be updated for every row in the whole table?
One way to handle this would be to declare another variable and set it with the PK of the row that is updated, then use a where clause to limit the update to just that row. Something like this:
DECLARE #id int
SELECT #id = Record_ID FROM INSERTED
-- body of your trigger here
WHERE Record_ID = #id
I like your padding code. It looks good to me.