sql - Update Trigger to populate a ModifyDate field - sql

I'm looking for an example of a good update trigger to update the ModifyDate field of a table.
It would be nice to handle the case where an update command updated more than one record in the table.
Is there a good template or tutorial for this?

Here's a cut and paste (and rename, to protect the innocent) of one I wrote quite some time ago (aka it works):
CREATE TRIGGER dbo.TR_iu_MyTable__LastUpdated
on dbo.MyTable
after insert, update
AS
SET NOCOUNT on
UPDATE dbo.MyTable
set LastUpdated = getdate()
where MyTableId in (select MyTableId from inserted)

UPDATE {tablename}
SET ModifyDate = GETDATE()
FROM inserted
WHERE {tablename}.{primarykey} = inserted.{primarykey}
Placed in a trigger tagged for INSERT and UPDATE actions will address your problem.
You could also do something similar for a CreateDate
UPDATE {tablename}
SET CreateDate = GETDATE()
FROM inserted
WHERE {tablename}.{primarykey} = inserted.{primarykey}
placed in a trigger tagged for INSERT action only.

Related

Creating an INSERT TRIGGER that updates CreatedBy and UpdatedBy without firing the UPDATE TRIGGER on same table

I am trying to create an INSERT TRIGGER and UPDATE TRIGGER on all tables in my database that manage CreatedBy and UpdatedBy fields.
The problem that I am running into is that the following is in my INSERT trigger:
UPDATE MyTable
SET CreatedBy = INSERTED.CreatedBy,
InsertDate = GetDate(),
UpdatedBy = INSERTED.UpdatedBy,
UpdateDate = GetDate()
FROM INSERTED
WHERE MyTable.Id = INSERTED.Id
The problem is that this UPDATE statement is additionally triggering the UPDATE trigger. I can not have this happen. How can I prevent this?
I found a built in SQL function called IF TRIGGER_NESTLEVEL().
I was able to wrap the update trigger with the following to prevent the update trigger from running when the insert trigger runs:
IF TRIGGER_NESTLEVEL() < 2
--Trigger script here
END

How to update specific row in datecolumn to date today after update on other column using after update trigger?

How to update date Column DateMod to today's date when Column CustomerProductID is updated (not inserted) using an after update trigger in T-SQL?
Some background info: Table already contains list of products (key column Itemcode), once the CustomerProductID is received it changes the column for that particular row (product) from NULL to integer value. This update is the trigger to update column DateMod to todays date for the row (product).
I am using SSMS 2008 and have something like the following code which changes the whole date column, not the particular date field for the updated row:
CREATE TRIGGER trigger_name
ON Table1
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF UPDATE (CustomerProductID) BEGIN
Update Table1
SET DateMod=GETDATE()
END
END
I have read some solutions using old.value and new.value or using where exists (select from inserted/updated), but how does that work? If both methods work, which one is the most beneficial in this case?
Thanks a lot!
I prefer do this as a before update trigger (a logical thing . . . doing updates in after update triggers suggests infinite loops and is not allowed in some databases). But SQL Server doesn't support that.
In any case, the right syntax is to use inserted to join back to the original table:
CREATE TRIGGER trigger_name
ON Table1
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF UPDATE(CustomerProductID) BEGIN
Update t1
SET DateMod = GETDATE()
FROM Table1 t1 join
Inserted i
ON Table1.PrimaryKeyColumn = i.PrimaryKeyColumn
END
END
Change the code so PrimaryKeyColumn is the right primary key column.

Fire trigger on updates (excluding certain fields change)

I've defined my trigger like that:
CREATE TRIGGER [dbo].[trtablename]
ON [dbo].[tablename]
AFTER UPDATE
AS update tablename set row_version = row_version + 1
where id in (select id from inserted)
There's a field called Row_Status. It should be modified without incrementing row_version field. How do I make such a condition in the trigger?
You need to add a condition based on the UPDATE() function that can be called in triggers.
Something like:
CREATE TRIGGER [dbo].[trtablename] ON [dbo].[tablename]
AFTER UPDATE
AS
If not update(Row_Status)
begin
update tablename set row_version = row_version + 1
where id in (select id from inserted)
end
Depending on your table/columns and the likely UPDATE operations that might occur you may have to increase the complexity of the the check, but hopefully this points you in the correct direction.
The only down side to using the UPDATE function is that it will be true if the field is even mentioned in the update statement. Even if it is being set to itself.
CREATE TRIGGER [dbo].[trtablename]
ON [dbo].[tablename]
AFTER UPDATE
AS
IF NOT UPDATE (Row_Status)
update tablename set row_version = row_version + 1
where id in (select id from inserted)

Data Type that automatically stores the DateTime of the last transaction done, SQL Server 2008

I need to add a new column to an existing table, so that whenever a new row is added, or an existing row is edited, this column will be filled with the exact date and time of the transaction. I tried using TimeStamp but apparently TimeStamp it has nothing to do with Date time
It's just a binary representation of a consecutive number - it's only good for making sure a row hasn't change since it's been read. (Quoted from How to convert SQL Server's timestamp column to datetime format
Any help is highly appreciated
It sounds like you need to create a trigger to populate/update this new column. See the following: How to: Create trigger for auto update modified date with SQL Server 2008
You have to create a trigger on INSERT and UPDATE for the table and in the trigger you can use
UPDATE myTable
SET myColumn = GETDATE()
Your trigger should look somethign like
CREATE TRIGGER trigger_updateTimestamp
ON myTable
AFTER INSERT, UPDATE
AS
UPDATE myTable
SET myColumn = GETDATE()
WHERE ID = 'xyz'
try
ALTER TABLE myTable ADD CONSTRAINT [DF_myTable_myColumn] DEFAULT (getdate()) FOR [myColumn]
GO
... and a good practice is to have an extra column for edited date, and update using a trigger
CREATE TRIGGER trigger_updateMyTable
ON myTable
AFTER UPDATE
AS
IF EXISTS (SELECT * FROM INSERTED)
BEGIN
IF ΝΟΤ EXISTS (SELECT * FROM DELETED)
BEGIN
UPDATE myTable
SET myEditColumn = GETDATE()
WHERE ID IN (
SELECT
ID
FROM INSERTED
)
END
END

Trigger being called on all rows in database

I have written a trigger that I want to use for adding the date to a column in a record so that I can keep track of the insert of the item.
There are a large amount of inserts being called (about 20000) and I have noticed that the trigger will update all of the InsertDate columns associated with each item every time a new item is added. How can I make sure this happens to an item being inserted only one time.
My trigger is as follows:
SET ANSI_NULLS ON
SET QUOTED_INDENTIFIER ON
GO
CREATE TRIGGER [InsertDate_Item]
ON [dbo].[ItemHolder]
AFTER INSERT
NOT FOR REPLICATION
AS
UPDATE ItemHolder SET InsertDate = GETDATE()
Any help will be much appreciated.
Thanks
You need to restrict rows to those inserted... using the virtual trigger table INSERTED
CREATE TRIGGER [InsertDate_Item]
ON [dbo].[ItemHolder]
AFTER INSERT
NOT FOR REPLICATION
AS
SET NOCOUNT ON
UPDATE IH
SET InsertDate = GETDATE()
FROM
ItemHolder IH
JOIN
INSERTED INS ON IH.keycol = INS.keycol
Go
One thing: You'd be better adding a default to the table instead. No need for a trigger
ALTER TABLE ItemHolder ADD
CONSTRAINT DF_ItemHolder_InsertDate DEFAULT (GETDATE()) FOR InsertDate
If you are inserting records into a table, why don't you make the InsertDate field have a default value of GetDate()? That avoids the trigger altogether.
I'd go about what you're trying to do without a trigger. Just set the default value of the column to GetDate().
update ih
set ih.insertdate = GetDate()
from itemholder ih inner join inserted i
on ih.itemholderid = i.itemholderid
change:
UPDATE ItemHolder SET InsertDate = GETDATE()
to:
UPDATE ItemHolder SET InsertDate = GETDATE() WHERE InsertDate IS NULL
The above will only set InsertDate if it is null and you still want to use the trigger. Of course, this is assuming the default value of InsertDate is null. If this is not the case let me know.