Difference between FOR and AFTER triggers? - sql

What's the difference between FOR and AFTER triggers?

There is no difference, they do the same thing.
CREATE TRIGGER trgTable on dbo.Table FOR INSERT,UPDATE,DELETE
Is the same as
CREATE TRIGGER trgTable on dbo.Table AFTER INSERT,UPDATE,DELETE
An INSTEAD OF trigger is different, and fires before and instead of the insert and can be used on views, in order to insert the appropriate values into the underlying tables.

#Ben is absolutely right.
Here is MSDN article Exploring SQL Server Triggers
A paragraph from the article:
That syntax is also acceptable in older versions of SQL Server. However, now that there are two types of triggers in SQL Server 2000, I prefer to refer to FOR triggers as AFTER triggers. Thus, for the remainder of this article I will refer to either AFTER or INSTEAD OF triggers.
Like the AFTER trigger you saw earlier, this trigger prevents changes from being made to the lastname field. However, it implements this business rule differently than the previous example. Because the INSTEAD OF trigger fires in place of the UPDATE statement, the INSTEAD OF trigger then evaluates if the business rule test passes or not. If the business rule test passes, in order for the update to occur the INSTEAD OF trigger must explicitly invoke the UPDATE statement again.

AFTER specifies that the DML trigger is fired only when all operations specified in the triggering SQL statement have executed successfully. All referential cascade actions and constraint checks also must succeed before this trigger fires.
AFTER is the default when FOR is the only keyword specified.
AFTER triggers cannot be defined on views.
INSTEAD OF
Specifies that the DML trigger is executed instead of the triggering SQL statement, therefore, overriding the actions of the triggering statements. INSTEAD OF cannot be specified for DDL or logon triggers.
https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql

Related

Why is a trigger "instead of delete" not recursive?

I wanted to know how it is possible that I can execute DELETE query inside a trigger "Instead of DELETE" without calling the same trigger? Is it a SQL feature? Can somebody explain why it works this way?
From the docs
If an INSTEAD OF trigger defined on a table runs a statement against the table that would ordinarily fire the INSTEAD OF trigger again, the trigger isn't called recursively. Instead, the statement processes as if the table had no INSTEAD OF trigger and starts the chain of constraint operations and AFTER trigger executions. For example, if a trigger is defined as an INSTEAD OF INSERT trigger for a table. And, the trigger runs an INSERT statement on the same table, the INSERT statement launched by the INSTEAD OF trigger doesn't call the trigger again. The INSERT launched by the trigger starts the process of running constraint actions and firing any AFTER INSERT triggers defined for the table.
It works that way because that is how Microsoft have decided. Although I can't imagine recursing would ever be useful for INSTEAD OF.

Is the BEFORE Trigger statement executed before the DDL statement?

Is the BEFORE trigger statement executed before DDL statements or is it inside a DDL statement?
I'm building a small DBMS and currently developing the DDL, and I'm confused about handling the BEFORE statement.
Here's not a defined behaviour for it:
https://web.csulb.edu/colleges/coe/cecs/dbdesign/dbdesign.php?page=sql/ddldml.php
Oracle describes the behaviour but not what can come inside the preceding or following trigger or whether they can be DDL statements or not:
https://www.oracletutorial.com/plsql-tutorial/oracle-trigger/
"BEFORE" is part of the DDL statement that defines the trigger. It describes when the trigger fires in relation to a DML command on a table: i.e. BEFORE or AFTER the change to the data is actually made. This allows you to validate or modify the new data as it is being applied, or to add or modify dependent data like a child table after the parent table update is complete.
While you can technically embed DDL into the body of a trigger using "execute immediate", it is typically considered very bad practice to do so. Is there a specific use case you are considering for including DDL statements in a trigger?

Column Constraint Sql 2008

I have been trying to find out if I can make a column Open on Insert, and closed on Update.
What I mean by that, is I need a column that I can give it a value only on Insert, but if I try to give it a value with Update, the statement would fail.
I am working with SQL 2008...
You can't do this with constraints - you need to use triggers for this.
A trigger is a special kind of stored procedure that automatically executes when an event occurs in the database server. DML triggers execute when a user tries to modify data through a data manipulation language (DML) event. DML events are INSERT, UPDATE, or DELETE statements on a table or view.

FOR/AFTER in SQL triggers

I am newbie in SQL. I am reading about Triggers in SQL.I have got almost about Triggers. But in DML Triggers, we use FOR/AFTER keyword. I didn't get difference between FOR/AFTER and why we use FOR/AFTER keyword. I have already read on MSDN but didn't get the simple answer.
Can anyone explain me what is it?
Thanks in advance.
There is no difference between using FOR and AFTER.
I believe the original (pre 2000) syntax only used the FOR keyword. However, when INSTEAD OF triggers were introduced, the "FOR" keyword could seem quite confusing. "AFTER" more accurately conveys the type of trigger, and is more easily distinguished from "INSTEAD OF".
An INSTEAD OF trigger would be used if we wanted to transform what was inserted into the table, or prevent an insertion from taking place.
An AFTER trigger would more normally be used if we wanted to perform additional tasks, based on what has just occurred. For instance, you could have an "AFTER DELETE" trigger, that copied deleted rows into some kind of archive table. Basically, in an AFTER trigger, you more normally do still want the activity to occur.
From MSDN:
AFTER triggers are never executed if a constraint violation occurs; therefore, these triggers cannot be used for any processing that might prevent constraint violations.
And then:
You can request AFTER triggers by specifying either the AFTER or FOR keywords. Because the FOR keyword has the same effect as AFTER, DML triggers with the FOR keyword are also classified as AFTER triggers
It would seem there is no difference.
If I interpret your comments to the other answers correctly, you want to know why or when one uses the "FOR|AFTER" keywords.
It's simple: there are two kinds of triggers, the AFTER-trigger and the INSTEAD-OF-trigger.
The INSTEAD-OF-trigger for e.g. an insert action can be written as
create trigger myTrigger on myTable
INSTEAD OF insert
begin
(... code goes here ...)
end
and the AFTER-trigger can be written as either
create trigger myTrigger on myTable
AFTER insert
begin
(... code goes here ...)
end
or
create trigger myTrigger on myTable
FOR insert
begin
(... code goes here ...)
end
As Damien_The_Unbeliever mentions, the AFTER keyword is more readable than the FOR version, that is all.
They are the same. See this excerpt from BOL
"
FOR | AFTER
AFTER specifies that the DML trigger is fired only when all operations specified in the triggering SQL statement have executed successfully. All referential cascade actions and constraint checks also must succeed before this trigger fires.
AFTER is the default when FOR is the only keyword specified.
AFTER triggers cannot be defined on views.
"
According to what I observe, FOR is used in DDL trigger while AFTER is used in DML triggers. They have same way of working.

How do you priortize multiple triggers of a table?

I have a couple of triggers on a table that I want to keep separate and would like to priortize them.
I could have just one trigger and do the logic there, but I was wondering if there was an easier/logical way of accomplishing this of having it in a pre-defined order ?
Use sp_settriggerorder. You can specify the first and last trigger to fire depending on the operation.
sp_settriggerorder on MSDN
From the above link:
A. Setting the firing order for a DML trigger
The following example specifies that trigger uSalesOrderHeader be the first trigger to fire after an UPDATE operation occurs on the Sales.SalesOrderHeader table.
USE AdventureWorks;
GO
sp_settriggerorder
#triggername= 'Sales.uSalesOrderHeader',
#order='First',
#stmttype = 'UPDATE';
B. Setting the firing order for a DDL trigger
The following example specifies that trigger ddlDatabaseTriggerLog be the first trigger to fire after an ALTER_TABLE event occurs in the AdventureWorks database.
USE AdventureWorks;
GO
sp_settriggerorder
#triggername= 'ddlDatabaseTriggerLog',
#order='First',
#stmttype = 'ALTER_TABLE',
#namespace = 'DATABASE';
See here.
You can use sp_settriggerorder to define the order of each trigger on a table.
However, I would argue that you'd be much better off having a single trigger that does multiple things. This is particularly so if the order is important, since that importance will not be very obvious if you have multiple triggers. Imagine someone trying to support the database months/years down the track. Of course there are likely to be cases where you need to have multiple triggers or it really is better design, but I'd start assuming you should have one and work from there.
Rememebr if you change the trigger order, someone else could come by later and rearrange it again. And where would you document what the trigger order should be so a maintenance developer knows not to mess with the order or things will break? If two trigger tasks definitely must be performed in a specific order, the only safe route is to put them in the same trigger.