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 11: Writing Scripts and Batches 358 Technically speaking, we could do this with nested IF...ELSE statements, but: ❑ It would be much harder to read — especially if the rules were more complex. ❑ We would have to implement the code using a cursor (bad!) and examine each row one at a time. In short — yuck! A CASE statement is going to make this process relatively easy. What’s more, we’re going to be able to place our condition inline to our query and use it as part of a set operation — this almost always means that we’re going to get much better performance than we would with a cursor. Our marketing department has decided they would like to see what things would look like if we increased prices by 10 percent, so we’ll plug a 10 percent markup into a CASE statement, and, together with a little extra analysis, we’ll get the numbers we’re looking for: USE AdventureWorks2008; GO /* I’m setting up some holding variables here. This way, if we get asked ** to run the query again with a slightly different value, we’ll only have ** to change it in one place. */ DECLARE @Markup money; DECLARE @Multiplier money; SELECT @Markup = .10; -- Change the markup here SELECT @Multiplier = @Markup + 1; -- We want the end price, not the amount -- of the increase, so add 1 /* Now execute things for our results. Note that we’re limiting things ** to the top 10 items for brevity -- in reality, we either wouldn’t do this ** at all, or we would have a more complex WHERE clause to limit the ** increase to a particular set of products */ SELECT TOP 10 ProductID, Name, ListPrice, ListPrice * @Multiplier AS “Marked Up Price”, “New Price” = CASE WHEN FLOOR(ListPrice * @Multiplier + .24) > FLOOR(ListPrice * @Multiplier) THEN FLOOR(ListPrice * @Multiplier) + .95 WHEN FLOOR(ListPrice * @Multiplier + .5) > FLOOR(ListPrice * @Multiplier) THEN FLOOR(ListPrice * @Multiplier) + .75 ELSE FLOOR(ListPrice * @Multiplier) + .49 END FROM Production.Product WHERE ProductID % 10 = 0 -- this is just to help the example ORDER BY ProductID DESC; The FLOOR function you see here is a pretty simple one — it takes the value supplied and rounds down to the nearest integer.
Now, I don’t know about you, but I get very suspicious when I hear the word “analysis” come out of someone’s lips — particularly if that person is in a marketing or sales role. Don’t get me wrong — those people are doing their jobs just like I am. The thing is, once they ask a question one way, they usually want to ask the same question another way. That being the case, I went ahead and set this up as a script — now all we need to do when they decide they want to try it with 15 percent is make a change to the initialization value of @Markup. Let’s see what we got this time with that 10 percent markup though: ProductID Name ListPrice Marked Up Price New Price --------- ------------------------------ ----------- ---------------- ----------- 990 Mountain-500 Black, 42 539.99 593.989 593.9500 980 Mountain-400-W Silver, 38 769.49 846.439 846.4900 970 Touring-2000 Blue, 46 1214.85 1336.335 1336.4900 960 Touring-3000 Blue, 62 742.35 816.585 816.7500 950 ML Crankset 256.49 282.139 282.4900 940 HL Road Pedal 80.99 89.089 89.4900 930 HL Mountain Tire 35.00 38.50 38.7500 920 LL Mountain Frame - Silver, 52 264.05 290.455 290.4900 910 HL Mountain Seat/Saddle 52.64 57.904 57.9500 900 LL Touring Frame - Yellow, 50 333.42 366.762 366.9500 (10 row(s) affected) Look these over for a bit, and you’ll see that the results match what we were expecting. What’s more, we didn’t have to build a cursor to do it. Looping with the WHILE Statement The WHILE statement works much as it does in other languages to which you have probably been exposed. Essentially, a condition is tested each time you come to the top of the loop. If the condition is still TRUE, then the loop executes again — if not, you exit. The syntax looks like this: WHILE | [BEGIN [BREAK] | [CONTINUE] END] Chapter 11: Writing Scripts and Batches While you can just execute one statement (much as you do with an IF statement), you’ll almost never see a WHILE that isn’t followed by a BEGIN...END with a full statement block. The BREAK statement is a way of exiting the loop without waiting for the bottom of the loop to come and the expression to be re-evaluated. I’m sure I won’t be the last to tell you this, but using a BREAK is generally thought of as something of bad form in the classical sense. I tend to sit on the fence on this one. I avoid using them if reasonably possible. Most of the time, I can indeed avoid them just by moving a statement or two around while still 359
- Page 346 and 347: Chapter 10: Views AW00000676 43659
- Page 348 and 349: Chapter 10: Views NULL values will
- Page 350 and 351: Chapter 10: Views Editing V iews wi
- Page 352 and 353: Chapter 10: Views 314 There are fou
- Page 354 and 355: Chapter 10: Views Editing Views in
- Page 356 and 357: Chapter 10: Views 318 In addition,
- Page 358 and 359: Chapter 10: Views 320 from the firs
- Page 360 and 361: Chapter 10: Views You can get the y
- Page 363 and 364: 11 Writing Scripts and Batches Whet
- Page 365 and 366: Next we have a DECLARE statement to
- Page 367 and 368: I’m not going to pick any bones a
- Page 369 and 370: Using @@IDENTITY @@IDENTITY is one
- Page 371 and 372: How It Works What we’re doing in
- Page 373 and 374: DECLARE @RowCount int; --Notice the
- Page 375 and 376: When the editing tool encounters a
- Page 377 and 378: When you think about it, this seems
- Page 379 and 380: So, let’s try a quick query direc
- Page 381 and 382: We now have our text file source fo
- Page 383 and 384: Let’s build an example in the Adv
- Page 385 and 386: DECLARE @InVar varchar(50); DECLARE
- Page 387 and 388: -- This won’t work DECLARE @Numbe
- Page 389 and 390: -- Now we’re run our conditional
- Page 391 and 392: Out of the condition from inner con
- Page 393 and 394: A Simple CASE A simple CASE takes a
- Page 395: 3 8 More Than One Apart 2 2 Ends Wi
- Page 399 and 400: The WAITFOR statement does exactly
- Page 401 and 402: IF @ErrorNo = 2714 -- Object exists
- Page 403: Chapter 11: Writing Scripts and Bat
- Page 406 and 407: Chapter 12: Stored Procedures Creat
- Page 408 and 409: Chapter 12: Stored Procedures Dropp
- Page 410 and 411: Chapter 12: Stored Procedures Suppl
- Page 412 and 413: Chapter 12: Stored Procedures 374 [
- Page 414 and 415: Chapter 12: Stored Procedures Confi
- Page 416 and 417: Chapter 12: Stored Procedures Now,
- Page 418 and 419: Chapter 12: Stored Procedures SQL S
- Page 420 and 421: Chapter 12: Stored Procedures 382 c
- Page 422 and 423: Chapter 12: Stored Procedures It wo
- Page 424 and 425: Chapter 12: Stored Procedures 386 r
- Page 426 and 427: Chapter 12: Stored Procedures 388 -
- Page 428 and 429: Chapter 12: Stored Procedures Note
- Page 430 and 431: Chapter 12: Stored Procedures 392 n
- Page 432 and 433: Chapter 12: Stored Procedures All t
- Page 434 and 435: Chapter 12: Stored Procedures Sproc
- Page 436 and 437: Chapter 12: Stored Procedures When
- Page 438 and 439: Chapter 12: Stored Procedures 400 @
- Page 440 and 441: Chapter 12: Stored Procedures I’d
- Page 442 and 443: Chapter 12: Stored Procedures match
- Page 444 and 445: Chapter 12: Stored Procedures There
Now, I don’t know about you, but I get very suspicious when I hear the word “analysis” come out of<br />
someone’s lips — particularly if that person is in a marketing or sales role. Don’t get me wrong — those<br />
people are doing their jobs just like I am. The thing is, once they ask a question one way, they usually<br />
want to ask the same question another way. That being the case, I went ahead and set this up as a<br />
script — now all we need to do when they decide they want to try it with 15 percent is make a change to<br />
the initialization value of @Markup. Let’s see what we got this time with that 10 percent markup though:<br />
ProductID Name ListPrice Marked Up Price New Price<br />
--------- ------------------------------ ----------- ---------------- -----------<br />
990 Mountain-500 Black, 42 539.99 593.989 593.9500<br />
980 Mountain-400-W Silver, 38 769.49 846.439 846.4900<br />
970 Touring-2000 Blue, 46 1214.85 1336.335 1336.4900<br />
960 Touring-3000 Blue, 62 742.35 816.585 816.7500<br />
950 ML Crankset 256.49 282.139 282.4900<br />
940 HL Road Pedal 80.99 89.089 89.4900<br />
930 HL Mountain Tire 35.00 38.50 38.7500<br />
920 LL Mountain Frame - Silver, 52 264.05 290.455 290.4900<br />
910 HL Mountain Seat/Saddle 52.64 57.904 57.9500<br />
900 LL Touring Frame - Yellow, 50 333.42 366.762 366.9500<br />
(10 row(s) affected)<br />
Look these over for a bit, and you’ll see that the results match what we were expecting. What’s more, we<br />
didn’t have to build a cursor to do it.<br />
Looping with the WHILE Statement<br />
The WHILE statement works much as it does in other languages to which you have probably been<br />
exposed. Essentially, a condition is tested each time you come to the top of the loop. If the condition is<br />
still TRUE, then the loop executes again — if not, you exit.<br />
The syntax looks like this:<br />
WHILE <br />
|<br />
[BEGIN<br />
<br />
[BREAK]<br />
| <br />
[CONTINUE]<br />
END]<br />
Chapter 11: Writing Scripts and Batches<br />
While you can just execute one statement (much as you do with an IF statement), you’ll almost never<br />
see a WHILE that isn’t followed by a BEGIN...END with a full statement block.<br />
The BREAK statement is a way of exiting the loop without waiting for the bottom of the loop to come and<br />
the expression to be re-evaluated.<br />
I’m sure I won’t be the last to tell you this, but using a BREAK is generally thought of as something of<br />
bad form in the classical sense. I tend to sit on the fence on this one. I avoid using them if reasonably<br />
possible. Most of the time, I can indeed avoid them just by moving a statement or two around while still<br />
359