Beginning Microsoft SQL Server 2008 ... - S3 Tech Training
Beginning Microsoft SQL Server 2008 ... - S3 Tech Training Beginning Microsoft SQL Server 2008 ... - S3 Tech Training
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
- Page 444 and 445: Chapter 12: Stored Procedures There
- Page 446 and 447: Chapter 12: Stored Procedures 408 f
- Page 449 and 450: 13 User-Defined Functions Well, her
- Page 451 and 452: types!), except for BLOBs, cursors,
- Page 453 and 454: We get back the same set as with th
- Page 455 and 456: AS RETURN (SELECT BusinessEntityID,
- Page 457 and 458: in your relational database. These
- Page 459 and 460: AS BEGIN ( EmployeeID int NOT NULL,
- Page 461 and 462: So, as you can see, we can actually
- Page 463 and 464: Despite being schema-bound, this on
- Page 465 and 466: 14 Transactions and Locks This is o
- Page 467 and 468: we are unable or do not want to com
- Page 469 and 470: Figure 14-1 Data needed Data in cac
- Page 471 and 472: Transaction 4 This transaction wasn
- Page 473 and 474: Oops — problem!!! Transaction 2 h
- Page 475 and 476: The only cure for this is setting y
- Page 477 and 478: Exclusive Locks Exclusive locks are
- Page 479 and 480: Also: ❑ The Sch-S is compatible w
- Page 481 and 482: The syntax for switching between th
- Page 483 and 484: As with most things in life, howeve
- Page 485 and 486: purchased. Process 2 records sales;
- Page 487: Chapter 14: Transactions and Locks
- Page 490 and 491: Chapter 15: Triggers the world’s
- Page 492 and 493: Chapter 15: Triggers WITH ENCRYPTIO
- Page 496 and 497: Chapter 15: Triggers 458 To illustr
- Page 498 and 499: Chapter 15: Triggers 460 IF EXISTS
- Page 500 and 501: Chapter 15: Triggers ❑ Feeding de
- Page 502 and 503: Chapter 15: Triggers Trigger Firing
- Page 504 and 505: Chapter 15: Triggers Like regular t
- Page 506 and 507: Chapter 15: Triggers The COLUMNS_UP
- Page 508 and 509: Chapter 15: Triggers This is the sa
- Page 510 and 511: Chapter 15: Triggers 472 we have th
- Page 512 and 513: Chapter 16: A Brief XML Primer So,
- Page 514 and 515: Chapter 16: A Brief XML Primer Figu
- Page 516 and 517: Chapter 16: A Brief XML Primer Elem
- Page 518 and 519: Chapter 16: A Brief XML Primer ❑
- Page 520 and 521: Chapter 16: A Brief XML Primer 482
- Page 522 and 523: Chapter 16: A Brief XML Primer Name
- Page 524 and 525: Chapter 16: A Brief XML Primer The
- Page 526 and 527: Chapter 16: A Brief XML Primer 2. W
- Page 528 and 529: Chapter 16: A Brief XML Primer SQL
- Page 530 and 531: Chapter 16: A Brief XML Primer So,
- Page 532 and 533: Chapter 16: A Brief XML Primer If,
- Page 534 and 535: Chapter 16: A Brief XML Primer 496
- Page 536 and 537: Chapter 16: A Brief XML Primer Note
- Page 538 and 539: Chapter 16: A Brief XML Primer RAW
- Page 540 and 541: Chapter 16: A Brief XML Primer AUTO
- Page 542 and 543: Chapter 16: A Brief XML Primer EXPL
<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