Help Understanding the inserted and deleted Table SQL Server - sql

If a run an INSERT INTO statement that triggers an INSERT AFTER trigger. What table/row(s) does the inserted and deleted objects represent in the trigger? For example,
INSERT INTO Person.person (personID, name) VALUES (1, 'robert')
CREATE TRIGGER myTrigger
ON Person.person
AFTER INSERT AS
BEGIN
insert into Person.PersonMovies (personID, movieID)
select inserted.personID from inserted _--i know the code is incomplete, but i'm curious only about the inserted part._
END
I'm confused as to what records are held by the inserted table. Would it be the records in the insert statement that triggered the trigger or the Person.PersonMovies table?

Yes, the inserted/deleted tables gives your trigger code access to the records changed by the statement that caused (triggered) the trigger. Also remember that your statements could have effected multiple rows, so your deleted or inserted tables could have multiple records.

The rows in the pseudotables inserted and deleted are based on the table defined in you ON clause.

The Inserted table holds the rows from the original Insert statement that caused the trigger to fire.
See also this MSDN article.

The inserted and deleted pseudotables hold one record for each row in the table that was created or deleted by the statement that fired the trigger. For an update, the deleted table holds the old version of the records, and the inserted table holds the new. The schema of the pseudotables matches the actual table.

Related

How to fire trigger after all records inserted?

In SQL server, when does a trigger get fired?
The problem is, I have a table where 45,000 records are going to be inserted.
And I want to copy all 45k records to other tables.
But I don't want the trigger to run on every insert, i.e 45000 times trigger.
My trigger is basically copying record from TableA to TableB.
Trigger:
Create trigger tri_1
on TableA
after insert
as
Begin
Insert into TableB (ID,Name,Others)
select ID,Name,Others from TableA
inner join inserted
on inserted.ID = TableA.ID
End
The above is just the template of my trigger.
Also, I have a question, the trigger mentioned above, how is it working? like firing for each row or after all insert is done?
In SQL Server, the trigger is fired when the insert statement is completed.
In some databases, the trigger is executed for each row inserted (in those databases for each row is often part of the syntax). By contrast, SQL Server keeps track of the changed rows, which is why they are stored in table-like structures, inserted and deleted -- and it is a mistake to assume that these contain only one row.

Delete trigger not inserting record

Need a trigger which runs on deletion.
The code I wrote is not working: It is firing the trigger but is not inserting any records.
I want it to insert the to be deleted row in a audit table.
My code:
CREATE TRIGGER [EXERCISE].[delete_trigger] ON [EXERCISE].[Fact_Sales]
AFTER DELETE
AS
INSERT INTO [EXERCISE].[Fact_Sales_Audit](City_ID,Product_ID,Time_ID,Created_Date,Updated_Date)
SELECT F.City_ID,F.Product_ID,F.Time_ID,F.Created_Date,F.Updated_Date
FROM [EXERCISE].[Fact_Sales] F
JOIN deleted D
ON F.Fact_Sales_ID = D.Fact_Sales_ID
PRINT 'Deleted row entered.'
It is not working. Reason I suspect is- the row is being deleted from the table before the trigger is fired and thats why it is not able to join and hence not inserting any records. But when I debug and print messages I can see that trigger happens before deletion.
Can someone please explain me how exactly does this trigger work?
You are deleting rows from the [EXERCISE].[Fact_Sales] table, yet in your trigger you are joining to this table, expecting the records to still be there - they are not.
At that point, the Deleted pseudo-table has the same schema as the [EXERCISE].[Fact_Sales] table, but with the rows you have just deleted in it. Instead of trying to join back to a table for rows you know aren't there any more, just use the Deleted table directly for your insert:
CREATE TRIGGER [EXERCISE].[delete_trigger]
ON [EXERCISE].[Fact_Sales]
AFTER DELETE
AS
INSERT INTO [EXERCISE].[Fact_Sales_Audit](City_ID,Product_ID,Time_ID,Created_Date,Updated_Date)
SELECT D.City_ID,
D.Product_ID,
D.Time_ID,
D.Created_Date,
D.Updated_Date
FROM deleted D
The trigger does fire after the delete on the main table, as the AFTER DELETE syntax implies. It fires somewhere between when the delete statement is executed, and before the control is returned to the user. It takes place in the same transaction - e.g. if the delete was rolled back for whatever reason, the inserts performed by the trigger would also be rolled back.
You should simplify your trigger definition to fetch just deleted row(s) from virtual table DELETED. What will happen is your deleted rows will be temporarily stored in that table and then will be inserted into audit table.
NB! Be sure you have set primary key on your Fact_Sales table.
CREATE TRIGGER [delete_trigger] ON [Fact_Sales]
FOR DELETE
AS
INSERT INTO [Fact_Sales_Audit](Fact_Sales_Id,City_ID,Product_ID,Time_ID,Created_Date,Updated_Date)
SELECT Fact_Sales_Id,City_ID,Product_ID,Time_ID,Created_Date,Updated_Date
FROM DELETED

SQL Server INSERT trigger does not work

I have a trigger to copy over the data from Table A to table B when table A is changed
The trigger is like this :
ALTER TRIGGER ATrigger
ON A AFTER INSERT, DELETE, UPDATE
AS
BEGIN
SET NOCOUNT ON;
DELETE FROM B WHERE id IN (SELECT id FROM deleted)
INSERT INTO B(Id, col1,col2) (SELECT i.Id, i.col1, i.col2 FROM inserted i)
END
But i see not all the data inserted in A are copied to B, the data copied seems very random
I was searching around, found it might caused by multi-insert, someone is suggesting using cusor, but i think for mine, it should be ok to insert or delete from the inserted, deleted table using this two sql.
Please advise, thanks!
I'm not certain this is your problem but your trigger has 2 "gotchas". First on an insert the deleted table will have no rows in it so no deletes will be done. Second is the reverse and potentially your problem. On a delete the inserted table has no rows. So all of the IDs are going to be deleted from table B but not re-inserted. On top of this if ID is not a unique key for table A then when you insert a second copy of it you will be deleting all of your history in table B and only adding the "new" history.
If you can provide more information on the structure of the 2 tables and the purpose of the trigger, not to mention any patterns on the rows being inserted or not being inserted as the case may be we can be of more help.

SQL update using values from the same record

In the following statement, will f1 always get the value that f2 used to have? Or will f2 sometimes get updated first and f1 winds up with NULL? I am under the impression that the new values are not available within the statement, that f2 has the old value while processing the record, but I can't find an authoritative place that says this.
UPDATE x
SET
x.f1 = x.f2,
x.f2 = NULL
Conceptually the operation happens "all at once" so it will use the "before" values
Indeed
UPDATE x
SET
x.f1 = x.f2,
x.f2 = x.f1
would also work fine to swap the two column values.
f1 will always get f2's previous value before the UPDATE.
Technically speaking the record is deleted, and reinserted. So SQL will work out what the new record should be, then delete the current record, and insert the new record afterwards.
This article regarding SQL Triggers may help explain:
The deleted table stores copies of the affected rows during DELETE and UPDATE statements. During the execution of a DELETE or UPDATE statement, rows are deleted from the trigger table and transferred to the deleted table. The deleted table and the trigger table ordinarily have no rows in common.
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.
http://msdn.microsoft.com/en-us/library/ms191300.aspx

Get last row inserted

I have a trigger that inserts a record into a diff table but I need to get that record that was inserted inside the trigger, how do I do it? There is no identity field, only account_nbr that is generated by a separate trigger on the insert table.
I don't know if there is sql statements to retrieve a row that was just inserted.
DB is Sql Server 2008.
The OUTPUT clause will give you back the records you have just inserted: http://msdn.microsoft.com/en-us/library/ms177564.aspx
If you mean the rows inserted before the trigger invoked, they are in the inserted pseudo-table.