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 The COLUMNS_UPDATED() Function 468 This one works somewhat differently from UPDATE(), but has the same general purpose. What COLUMNS_ UPDATED() gives us is the ability to check multiple columns at one time. In order to do this, the function uses a bitmask that relates individual bits in one or more bytes of varbinary data to individual columns in the table. It ends up looking something like Figure 15-4. Figure 15-4 In this case, our single byte of data is telling us that the second, third, and sixth columns were updated — the rest were not. In the event that there are more than eight columns, SQL Server just adds another byte on the right-hand side and keeps counting (see Figure 15-5). 0 1 Figure 15-5 0 1 Column 1 Column 2 Column 3 Column 4 Column 5 Column 6 Column 7 Column 8 0 0 0 0 0 First Byte Second Byte This time the second, ninth, and fourteenth columns were updated. 0 Column 1, value = 1 Column 2, value = 2 Column 3, value = 4 Column 4, value = 8 Column 5, value = 16 Column 6, value = 32 Column 7, value = 64 Column 8, value = 128 1 0 0 1 0 0 1 0 Column 9 Column 10 Column 11 Column 12 Column 13 Column 14 Column 15 Column 16 0 0 0 1 0 0 I can hear you out there: “Gee, that’s nice — but how do I make any use of this?” Well, to answer that, we have to get into the world of boolean algebra. Making use of this information means that you need to add up the binary value of all the bytes, considering the leftmost digit to be the least significant. So, if you want your comparison to take into account 2,
5, and 7, then you need to add the binary value of each bit: 2 + 16 + 64. Then you need to compare the sum of the binary values of your columns to the bitmask by using bitwise operators: ❑ | Represents bitwise OR ❑ & Represents bitwise AND ❑ ^ Represents bitwise Exclusive OR As I read back over what I’ve just written, I realize that it is correct, but about as clear as mud, so let’s look a little closer at what I mean with a couple of examples. Imagine that we updated a table that contained five columns. If we updated the first, third, and fifth columns, the bitmask used by COLUMNS_UPDATED would contain 10101000, from 1 + 4 + 16 = 21. We could use: ❑ COLUMNS_UPDATED() > 0 to find out if any column was updated ❑ COLUMNS_UPDATED() ^ 21 = 0 to find out if all of the columns specified (in this case 1, 3, and 5) were updated and nothing else was ❑ COLUMNS_UPDATED() & 21 = 21 to find out if all of the columns specified were updated, but the state of other columns doesn’t matter ❑ COLUMNS_UPDATED | 21 != 21 to find out if any column other than those we’re interested in was updated Understand that this is tough stuff — boolean math is not exactly the easiest of concepts to grasp for most people, so check things carefully and TEST, TEST, TEST! Keep It Short and Sweet I feel like I’m stating the obvious here, but it’s for a good reason. I can’t tell you how often I see bloated, stupid code in sprocs and triggers. I don’t know whether it’s that people get in a hurry, or if they just think that the medium they are using is fast anyway, so it won’t matter. Remember that a trigger is part of the same transaction as the statement in which it is called. This means the statement is not complete until your trigger is complete. Think about it — if you write long-running code in your trigger, this means that every piece of code that you create that causes that trigger to fire will, in turn, be long running. This can really cause heartache when you are trying to figure out why your code is taking so long to run. You write what appears to be a very efficient sproc, but it performs terribly. You may spend weeks and yet never figure out that your sproc is fine — it just fires a trigger that isn’t. Don’t Forget Triggers When Choosing Indexes Chapter 15: Triggers Another common mistake. You look through all your sprocs and views figuring out what the best mix of indexes is — and totally forget that you have significant code running in your triggers. 469
- 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 494 and 495: Chapter 15: Triggers FOR|AFTER The
- 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 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
- Page 544 and 545: Chapter 16: A Brief XML Primer Chec
- Page 546 and 547: Chapter 16: A Brief XML Primer 508
- Page 548 and 549: Chapter 16: A Brief XML Primer 510
- Page 550 and 551: Chapter 16: A Brief XML Primer 512
- Page 552 and 553: Chapter 16: A Brief XML Primer The
- Page 554 and 555: Chapter 16: A Brief XML Primer 516
Chapter 15: Triggers<br />
The COLUMNS_UPDATED() Function<br />
468<br />
This one works somewhat differently from UPDATE(), but has the same general purpose. What COLUMNS_<br />
UPDATED() gives us is the ability to check multiple columns at one time. In order to do this, the function<br />
uses a bitmask that relates individual bits in one or more bytes of varbinary data to individual columns<br />
in the table. It ends up looking something like Figure 15-4.<br />
Figure 15-4<br />
In this case, our single byte of data is telling us that the second, third, and sixth columns were<br />
updated — the rest were not.<br />
In the event that there are more than eight columns, <strong>SQL</strong> <strong>Server</strong> just adds another byte on the right-hand<br />
side and keeps counting (see Figure 15-5).<br />
0 1<br />
Figure 15-5<br />
0 1<br />
Column 1<br />
Column 2<br />
Column 3<br />
Column 4<br />
Column 5<br />
Column 6<br />
Column 7<br />
Column 8<br />
0 0 0 0 0<br />
First Byte Second Byte<br />
This time the second, ninth, and fourteenth columns were updated.<br />
0<br />
Column 1, value = 1<br />
Column 2, value = 2<br />
Column 3, value = 4<br />
Column 4, value = 8<br />
Column 5, value = 16<br />
Column 6, value = 32<br />
Column 7, value = 64<br />
Column 8, value = 128<br />
1 0 0 1 0 0<br />
1 0<br />
Column 9<br />
Column 10<br />
Column 11<br />
Column 12<br />
Column 13<br />
Column 14<br />
Column 15<br />
Column 16<br />
0 0 0 1 0 0<br />
I can hear you out there: “Gee, that’s nice — but how do I make any use of this?” Well, to answer that,<br />
we have to get into the world of boolean algebra.<br />
Making use of this information means that you need to add up the binary value of all the bytes, considering<br />
the leftmost digit to be the least significant. So, if you want your comparison to take into account 2,