Beginning Microsoft SQL Server 2008 ... - S3 Tech Training

Beginning Microsoft SQL Server 2008 ... - S3 Tech Training Beginning Microsoft SQL Server 2008 ... - S3 Tech Training

cdn.s3techtraining.com
from cdn.s3techtraining.com More from this publisher
17.06.2013 Views

Chapter 15: Triggers FOR|AFTER The FOR (or, alternatively, you can use AFTER) clause indicates under what type of action(s) you want this trigger to fire. You can have the trigger fire whenever there is an INSERT, UPDATE, or DELETE, or any mix of the three. So, for example, your FOR clause could look something like: … or: … or: FOR INSERT, DELETE FOR UPDATE, INSERT FOR DELETE As stated in the section about the ON clause, triggers declared using the FOR or AFTER clause can be attached only to tables — no views are allowed (see INSTEAD OF triggers for those). INSERT Trigger The code for any trigger that you mark as being FOR INSERT will be executed anytime that someone inserts a new row into your table. For each row that is inserted, SQL Server will create a copy of that new row and insert it in a special table that exists only within the scope of your trigger. That table is called Inserted, and we’ll see much more of it over the course of this chapter. The big thing to understand is that the Inserted table lives only as long as your trigger does. Think of it as not existing before your trigger starts or after your trigger completes. DELETE Trigger This works much the same as an INSERT trigger does, save that the Inserted table will be empty (after all, you deleted rather than inserted, so there are no records for the Inserted table). Instead, a copy of each record that was deleted is inserted into another table called Deleted. That table, like the Inserted table, is limited in scope to just the life of your trigger. UPDATE Trigger More of the same, save for a twist. The code in a trigger declared as being FOR UPDATE will be fired whenever an existing record in your table is changed. The twist is that there’s no such table as UPDATED. Instead, SQL Server treats each row as if the existing record had been deleted and a totally new record was inserted. As you can probably guess from that, a trigger declared as FOR UPDATE contains not one but two special tables called Inserted and Deleted. The two tables have exactly the same number of rows, of course. WITH APPEND 456 WITH APPEND is something of an oddball and, in all honesty, you’re pretty unlikely to use it; nonetheless, we’ll touch on it briefly. WITH APPEND applies only when you are running in 6.5 compatibility mode (which can be set using sp_dbcmptlevel) — something that should be exceedingly rare at this point (it’s been out of date for nearly a decade now).

SQL Server 6.5 and prior did not allow multiple triggers of the same type on any single table. For example, if you had already declared a trigger called trgCheck to enforce data integrity on updates and inserts, then you couldn’t create a separate trigger for cascading updates. Once one update (or insert, or delete) trigger was created, that was it — you couldn’t create another trigger for the same type of action. WITH APPEND gets around this problem by explicitly telling SQL Server that we want to add this new trigger even though we already have a trigger of that type on the table — both will be fired when the appropriate trigger action (INSERT, UPDATE, DELETE) occurs. It’s a way of having a bit of both worlds. NOT FOR REPLICATION AS Adding this option slightly alters the rules for when the trigger is fired. With this option in place, the trigger will not be fired whenever a replication-related task modifies your table. Usually a trigger is fired (to do the housekeeping, cascading, and so on) when the original table is modified and there is often no point in doing it again. Exactly as it was with sprocs, this is the meat of the matter. The AS keyword tells SQL Server that your code is about to start. From this point forward, we’re into the scripted portion of your trigger. Using Triggers for Data Integrity Rules Although they shouldn’t be your first option, triggers can also perform the same functionality as a CHECK constraint or even a DEFAULT. The answer to the question “Should I use triggers vs. CHECK constraints?” is the rather definitive: “It depends.” If a CHECK can do the job, then it’s probably the preferable choice. There are times, however, when a CHECK constraint just won’t do the job, or when something inherent in the CHECK process makes it less desirable than a trigger. Examples of where you would want to use a trigger over a CHECK include: ❑ Your business rule needs to reference data in a separate table. ❑ Your business rule needs to check the delta (difference between before and after) of an UPDATE. ❑ You require a customized error message. Chapter 15: Triggers A summary table of when to use what type of data integrity mechanism is provided at the end of Chapter 6. This really just scratches the surface of things. Since triggers are highly flexible, deciding when to use them really just comes down to balancing your need to get something special done with the overhead triggers incur and other approaches you might take to address your need. Dealing with Requirements Sourced from Other Tables CHECK constraints are great — fast and efficient — but they don’t do everything you’d like them to. Perhaps the biggest shortcoming shows up when you need to verify data across tables. 457

<strong>SQL</strong> <strong>Server</strong> 6.5 and prior did not allow multiple triggers of the same type on any single table. For example,<br />

if you had already declared a trigger called trgCheck to enforce data integrity on updates and inserts,<br />

then you couldn’t create a separate trigger for cascading updates. Once one update (or insert, or delete)<br />

trigger was created, that was it — you couldn’t create another trigger for the same type of action. WITH<br />

APPEND gets around this problem by explicitly telling <strong>SQL</strong> <strong>Server</strong> that we want to add this new trigger<br />

even though we already have a trigger of that type on the table — both will be fired when the appropriate<br />

trigger action (INSERT, UPDATE, DELETE) occurs. It’s a way of having a bit of both worlds.<br />

NOT FOR REPLICATION<br />

AS<br />

Adding this option slightly alters the rules for when the trigger is fired. With this option in place, the trigger<br />

will not be fired whenever a replication-related task modifies your table. Usually a trigger is fired (to do<br />

the housekeeping, cascading, and so on) when the original table is modified and there is often no point<br />

in doing it again.<br />

Exactly as it was with sprocs, this is the meat of the matter. The AS keyword tells <strong>SQL</strong> <strong>Server</strong> that your<br />

code is about to start. From this point forward, we’re into the scripted portion of your trigger.<br />

Using Triggers for Data Integrity Rules<br />

Although they shouldn’t be your first option, triggers can also perform the same functionality as a CHECK<br />

constraint or even a DEFAULT. The answer to the question “Should I use triggers vs. CHECK constraints?”<br />

is the rather definitive: “It depends.” If a CHECK can do the job, then it’s probably the preferable choice.<br />

There are times, however, when a CHECK constraint just won’t do the job, or when something inherent in<br />

the CHECK process makes it less desirable than a trigger. Examples of where you would want to use a<br />

trigger over a CHECK include:<br />

❑ Your business rule needs to reference data in a separate table.<br />

❑ Your business rule needs to check the delta (difference between before and after) of an UPDATE.<br />

❑ You require a customized error message.<br />

Chapter 15: Triggers<br />

A summary table of when to use what type of data integrity mechanism is provided at the end of<br />

Chapter 6.<br />

This really just scratches the surface of things. Since triggers are highly flexible, deciding when to use<br />

them really just comes down to balancing your need to get something special done with the overhead<br />

triggers incur and other approaches you might take to address your need.<br />

Dealing with Requirements Sourced from Other Tables<br />

CHECK constraints are great — fast and efficient — but they don’t do everything you’d like them to. Perhaps<br />

the biggest shortcoming shows up when you need to verify data across tables.<br />

457

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!