Trigger after update to update linked server table - sql-server

Basically I have an app where upon column field change (update) another table on a linked server gets updated.
After modifying reference number through an app, this value gets updated in Table_A.
Now I wan't to trigger update of Table_B if Table_A column field reference number is updated.( only check for update of this very field )
USE [SRV1]
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[BenRef_UPDATE]
ON [dbo].[Table_A]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON
IF UPDATE(refNum)
UPDATE [EXPSRV1].[OPR].[protected].[TransferServiceArrangement]
SET PaymentDetailsBeneficiaryReferenceNumber = i.refNum
FROM inserted i
INNER JOIN deleted d
ON d.party= i.party
END;
Right now I am unable to update Table_A when Trigger is created, no change will occur, when I drop the trigger and modify number the change reflects on the Table_A.
What did I miss ?

Related

SQL server triggers : Deleted table empty after update

I have a database A, table t with a transactional replication to a database B table t
on B.t there is a trigger
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE OR ALTER TRIGGER [dbo].[synchro_trigger]
ON [dbo].[t]
FOR INSERT, UPDATE
AS
BEGIN
-- update case
IF EXISTS ( SELECT 0 FROM Deleted )
...
when running an update on A.t :
update A.t set field1='1' where id=?
the value is replicated then the trigger is called and SELECT 0 FROM Deleted exist;
the trigger does its job.
When updating ALL fields on table t (some get a different value, some get the same value)
update A.t set field1='1', field2='1', ... where id=?
the values (which are differents) are replicated then the triggrer is called BUT SELECT 0 FROM Deleted doesn't exist.
so the trigger does nothing, it is not what I want.
In case of update the previous row value is supposed to be inside Deleted, right?
How it is possible that the trigger doesn't receive the previous value inside the Delete table ?
Note :
it looks like the same issue as : SQLServer Update Trigger with empty DELETED logical table

SQL AFTER INSERT,UPDATE Trigger with condition if update specific column

I would like to create a trigger that inserts new datasets into the FREE08 table (see example code) either after insert on FREE03. This part works. But i also want to insert new dataset into FREE08 only if specific column (FK2) of FREE03 is updated. Thought this works with the "IF UPDATE(FK2) statement in the trigger.
What happens is i got a new dataset in FREE08 everytime i have any update in FREE03.
How can i get that?
Thanks for your support
USE [DB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[Einsatzhistorie Wechsler]
ON [dbo].[FREE03]
AFTER INSERT,UPDATE
AS
SET NOCOUNT ON;
IF UPDATE(FK2)
BEGIN
INSERT INTO FREE08
(
FK1,FK2,TEXT3,DATE1,TEXT2,DATE4
)
Select FK2,FK1,ID,DATE1,TEXT1,DATE11 From inserted
end
I've never found a real use for the UPDATE function, since it tells you whether a column was subject to UPDATE (I.e. appeared in the SET clause), not whether data actually changed. In addition, of course, triggers fire once per statement, not once per row, so your trigger may be dealing with a mixture of rows, some of which had their FK2 changed and some not.
It's usually better to use deleted and compare the previous/current values:
CREATE TRIGGER [dbo].[Einsatzhistorie Wechsler]
ON [dbo].[FREE03]
AFTER INSERT,UPDATE
AS
SET NOCOUNT ON;
INSERT INTO FREE08
(
FK1,FK2,TEXT3,DATE1,TEXT2,DATE4
)
Select i.FK2,i.FK1,i.ID,i.DATE1,i.TEXT1,i.DATE11
From inserted i
left join deleted d
on
i.ID = d.ID and
i.FK2 = d.FK2
where d.ID is null
Here I've assumed a) that ID represents an immutable primary key for the table and b) That FK2 isn't nullable.

Sql CretedDate Trigger

This is the query I used for creating a trigger to update the CreatedDate column of my table "websites"
create trigger [dbo].[trgrforcreateddate] on [dbo].[Websites]
after insert
as
update dbo.websites
set CreatedDate=getdate() from websites w inner join inserted i on w.website=i.website where w.website=i.website
It worked, only one should get updated with Created date (actually, the expected row is updated). But as a result I see
" rows updated"
Why?
For this you should be using a default constraint on CreatedDate instead of a trigger.
alter table dbo.websites add constraint df_websites_CreatedDate default getdate() for CreatedDate;
The trigger is not joining on a unique id, if it was you would see only 1 row affected for each insert. You should also use set nocount on; to prevent extra row result messages from being returned, but in this case it was good that it was not set so that you noticed the error.
alter trigger [dbo].[trgrforcreateddate] on [dbo].[Websites]
after insert
as
begin;
set nocount on;
update w
set w.CreatedDate=getdate()
from dbo.websites w
inner join inserted i
on w.id = i.id;
end;

adding data in column depending on another columns in same table

Dear
i already create one table for employee information with ASP.net interface
now i show add one operation in my table as below,
i have four columns( WorkDatey,WorkDatem,WorkDated,absentday) all the columns from integer type in table name employee.
now i should add new column (realworkdays) and the result here should be automatic save after entering previous data as example:
WorkDatey= 2011 ,
WorkDatem= 2 ,
WorkDated=14 ,
absentday=6
the operation should be : (2011*365)+(2*30)+(14)-(6) and result will store in column (realworkdays).
i already try it as trigger but i have some thing wrong:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER daysResult
ON [dbo].[employee]
AFTER insert
As
DECLARE #realworkdays int
BEGIN
SET NOCOUNT ON;
select WorkDatey,WorkDatem,WorkDated,absent from [dbo].[employee]
#realworkdays= (workdatey*350)+(workdatem*29)+(workdated)-(absent)
insert into [dbo].[employee] (totaldays)values (#realworkdays)
END
GO
Since you are using sql server 2005, i would suggest you use a computed column
ALTER TABLE employee DROP COLUMN realworkdays;
ALTER TABLE employee ADD COLUMN realworkdays AS (
(WorkDatey * 365) +
(WorkDatem * 30) +
(WorkDated) -
(absentday)
)
You can add the PERSISTED so it will store the data, optionally indexing it.
On a side note, your trigger is inserted a new row, instead of updating the value of the current row.
You are supposed to update the inserted records, not insert new ones.
So, it should be the UPDATE statement, and you can do both the calculations and the updates in one go.
CREATE TRIGGER daysResult
ON [dbo].[employee]
AFTER insert
AS
BEGIN
UPDATE employee
SET realworkdays = (inserted.workdatey*350)+(inserted.workdatem*29)+
(inserted.workdated)-(inserted.absent)
FROM inserted
WHERE employee.ID = inserted.ID
END
Still it would be better to use a computed column, as #The Scrum Meister has suggested.

SQL Server Update Trigger

I have never used triggers before in SQL server and I have looked around online but haven't found an answer to my question. Basically I am trying to write an Trigger that will run after a record has been updated in a table. This trigger will then update two additional tables based on the record that was updated in the first table.
The primary table with the trigger on it will be updating one record using a query like this:
UPDATE E.SM_T_RList
SET IsActive = 0
WHERE Guid = #Guid
I then want the trigger to do something like this:
ALTER TRIGGER [E].[IsActiveUpdate]
ON [E].[SM_T_RList]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE E.SM_T_BInfo
SET IsActive = 0
WHERE Guid = #Guid
UPDATE E.SM_T_RMachines
SET IsActive = 0
WHERE GUID = #GUID
END
The Guid that I want updated is being used by the primary table. But I can't figure out how I get the #Guid that I want updated into the trigger? Please help.
Thanks
Both the answers already posted suffer from the same problem - they're marking the other rows as Inactive, whenever any update occurs on your base table
Something like:
ALTER TRIGGER [E].[IsActiveUpdate]
ON [E].[SM_T_RList]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE E.SM_T_BInfo
SET IsActive = 0
WHERE Guid IN (SELECT Guid FROM INSERTED where IsActive=0)
UPDATE E.SM_T_RMachines
SET IsActive = 0
WHERE Guid IN (SELECT Guid FROM INSERTED where IsActive=0)
END
Would be more appropriate
Triggers in SQL Server operate on sets of rows not individual rows. You access these via the inserted and deleted pseudo tables. Assuming that you might want the value of isactive to cascade when previously inactive rows were made active you could use something like this.
ALTER TRIGGER [E].[IsActiveUpdate]
ON [E].[SM_T_RList]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE E.SM_T_BInfo
SET IsActive = i.IsActive
FROM INSERTED i JOIN E.SM_T_BInfo e
ON e.Guid = i.Guid
UPDATE E.SM_T_RMachines
SET IsActive = i.IsActive
FROM INSERTED i JOIN E.SM_T_BInfo e
ON e.Guid = i.Guid
END

Resources