I am interested to know about trigger execution in SQL Server.
I created an INSERT trigger for a table. And I insert 10 records from another table.
How many times the trigger called? One time or 10 times?
And how many records will be available in INSERTED table?
Triggers in SQL Server are called once per statement - so in your case:
the trigger is called ONCE for your INSERT statement
the pseudo table Inserted will contain all the 10 rows that you're inserting
See Data Points: Exploring SQL Server Triggers on MSDN Magazine for a more in-depth look at triggers
Related
I have a Microsoft SQL Server 2012 database with multiple tables.
All tables contain the same two columns DataRowModified (type datetime) and DataRowLastAuthor (type nvarchar(MAX)). And no, I can't put all those columns into a separate table, it's a requirement that each table directly contains those rows.
I wrote the trigger below for the table Events to automatically update the values of those two columns whenever a row gets updated:
CREATE TRIGGER [dbo].[Trigger_Events_UpdateMetadata]
ON [dbo].[Events]
FOR UPDATE
AS
BEGIN
UPDATE [dbo].[Events]
SET [DataRowModified] = GETDATE(),
[DataRowLastAuthor] = ORIGINAL_LOGIN()
WHERE [Id] IN (SELECT [Id] FROM INSERTED)
END
Now my question is whether I have to copy (and rename) this trigger for every table I have to use it with, or can I somehow write a global trigger that works on all (or a specified set of) tables? It has to know in which table/row the update happened though, because it has to modify it.
What would be the easiest way to implement an automatically maintained LastAuthor and LastModificationDate column into many tables as described?
A trigger in SQL Server is always bound to a single table - you cannot have "global" triggers or triggers attached to multiple tables at once.
If you need a trigger on your 50 tables - you need to write 50 trigger, one each for every table. No way around this.
The only way to avoid this would be to update those columns in your database layer of your application, so that those values would already be present when you save your row of data. Things like Entity Framework allow such "bulk operations" on multiple entities to e.g. update a last modified date and last user to modify the entity.
No, But multiple triggers could invoke the same stored procedure.
I have the same application on different hosts bulk inserting into the same table. Each bulk insert fires a trigger. The structure of the table is as follows:
Hostname Quantity
---------------------
BOX_1 10
BOX_1 15
BOX_1 20
BOX_1 11
If I have the following code as part of the trigger:
DECLARE #hostname VARCHAR(20)
SELECT #hostname = Hostname
FROM INSERTED
Each bulk insert contains only one hostname since the application is only capturing data from the box its running on, but if two machines bulk insert simultaneously into the same table, could the INSERTED table be a combination of bulk inserts from different machines?
Or will the triggers execute sequentially, meaning the INSERTED table will always contain data from only one application at a time?
I need to know if my code setting the #hostname variable has any possibility of not being confined to just one choice.
The INSERTED (and DELETED) table will only ever contain rows from the statement that caused the trigger to fire.
See here: https://msdn.microsoft.com/en-us/library/ms191300(v=sql.110).aspx
The inserted table stores copies of the affected rows during INSERT
and UPDATE statements. During an insert or update transaction, new
rows are added to both the inserted table and the trigger table. The
rows in the inserted table are copies of the new rows in the trigger
table.
The rows in these tables are effectively scoped to the insert/update/delete statement that caused the trigger to fire initially.
See also here for some more info: SQL Server Trigger Isolation / Scope Documentation
But bear in mind in your trigger design that some other insert or update operation (a manual bulk insert, or data maintenance) might cause your trigger to fire, and the assumption about the hostname may no longer hold. Probably this will be years down the line after you've moved on or forgotten about this trigger!
Is there any system table or dmv in SQL Server 2008 R2 that contains information regarding the last DML statement (except select) that was issued against any user table?
I see that in sys.tables there is a modify_date column but that's just for any table alteration (DDL statements).
I wouldn't want to create triggers on every table in the db nor a trigger on the database level for this scope.
The reason for this is that I would like to see when was the last time an insert, update or delete statement was made into each table in order to see if I can drop some of the tables that are no longer used - this is for a DWH db, where each table in the db is supposed to have any of these 3 operations at least once a week/month/quarter/year.
Option 1:
Enabling Change Data Capture for your DB.
Refer the below link for CDC:
http://technet.microsoft.com/en-us/library/cc627369%28v=sql.105%29.aspx
Option 2:
Create trigger for each table and do logging in common table whenever INSERT/UPDATE/DELETE happens in any table(Old traditional method).
The problem is I have inserted a new row in a table through procedure which have a AFTER INSERT trigger on it, what I want to do is to update only this new inserted row though trigger, is there any way to do this?
Yes.
Have you tried reading the documentation? I mean, at least once.
THe part where it tells you the trigger has a virtual table (inserted) with all the rows it processes (may be more than one actually, an insert can cover more than one row) and you can then use standard SQL on this (i.e. to find the updated rows in the real table and then update them)?
Your question is the textbook example of a simple standard tutorial trigger chapter 1.
A little google fu - "tsql trigger update inserted table".
Item 1: http://technet.microsoft.com/en-us/library/ms191300.aspx, named "Use the inserted and deleted Tables"
You could also just use search here instead of asking.
SQL Insert trigger to update INSERTED table values
A while ago i read the article for Trigger in SQL Server, and it said that i can use the Logical Table "Updated" for updated rows... And i got error:
System.Data.SqlClient.SqlException: Invalid object name 'Updated'.
After a while of google, i found out some more post that said only 2 logical tables available are: Inserted and Deleted...
I'm confused... What should i use since my Trigger rely on the Updated table that contain the updated row, and use it to insert to another table or the same table with new PK...
Thank you very much
The two dummy tables are called Inserted (available in INSERT and UPDATE triggers) and Deleted (available in DELETE and UPDATE triggers).
There is no Updated dummy table in SQL Server triggers.
For an FOR UPDATE trigger, the Deleted table contains the old values, while the Inserted table contains the new ones.
Marc