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 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

5, and 7, then you need to add the binary value of each bit: 2 + 16 + 64. Then you need to compare the<br />

sum of the binary values of your columns to the bitmask by using bitwise operators:<br />

❑ | Represents bitwise OR<br />

❑ & Represents bitwise AND<br />

❑ ^ Represents bitwise Exclusive OR<br />

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<br />

look a little closer at what I mean with a couple of examples.<br />

Imagine that we updated a table that contained five columns. If we updated the first, third, and fifth<br />

columns, the bitmask used by COLUMNS_UPDATED would contain 10101000, from 1 + 4 + 16 = 21. We<br />

could use:<br />

❑ COLUMNS_UPDATED() > 0 to find out if any column was updated<br />

❑ COLUMNS_UPDATED() ^ 21 = 0 to find out if all of the columns specified (in this case 1, 3, and<br />

5) were updated and nothing else was<br />

❑ COLUMNS_UPDATED() & 21 = 21 to find out if all of the columns specified were updated, but<br />

the state of other columns doesn’t matter<br />

❑ COLUMNS_UPDATED | 21 != 21 to find out if any column other than those we’re interested in<br />

was updated<br />

Understand that this is tough stuff — boolean math is not exactly the easiest of concepts to grasp for<br />

most people, so check things carefully and TEST, TEST, TEST!<br />

Keep It Short and Sweet<br />

I feel like I’m stating the obvious here, but it’s for a good reason.<br />

I can’t tell you how often I see bloated, stupid code in sprocs and triggers. I don’t know whether it’s that<br />

people get in a hurry, or if they just think that the medium they are using is fast anyway, so it won’t matter.<br />

Remember that a trigger is part of the same transaction as the statement in which it is called. This means<br />

the statement is not complete until your trigger is complete. Think about it — if you write long-running<br />

code in your trigger, this means that every piece of code that you create that causes that trigger to fire<br />

will, in turn, be long running. This can really cause heartache when you are trying to figure out why<br />

your code is taking so long to run. You write what appears to be a very efficient sproc, but it performs<br />

terribly. You may spend weeks and yet never figure out that your sproc is fine — it just fires a trigger<br />

that isn’t.<br />

Don’t Forget Triggers When Choosing Indexes<br />

Chapter 15: Triggers<br />

Another common mistake. You look through all your sprocs and views figuring out what the best mix of<br />

indexes is — and totally forget that you have significant code running in your triggers.<br />

469

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

Saved successfully!

Ooh no, something went wrong!