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 recognize keywords, but also understand their nature. In addition, you have Intellisense, a step debugger, code templates, the object browser, and more. Scripts are usually treated as a unit. That is, you are normally executing the entire script or nothing at all. They can make use of both system functions and local variables. As an example, let’s look at a script that would insert order records in the Accounting database that we created back in Chapter 5: USE Accounting; DECLARE @Ident int; INSERT INTO Orders (CustomerNo,OrderDate, EmployeeID) VALUES (1, GETDATE(), 1); SELECT @Ident = @@IDENTITY; INSERT INTO OrderDetails (OrderID, PartNo, Description, UnitPrice, Qty) VALUES (@Ident, ‘2R2416’, ‘Cylinder Head’, 1300, 2); SELECT ‘The OrderID of the INSERTed row is ‘ + CONVERT(varchar(8),@Ident); If you didn’t keep your populated version of the Accounting database, a script to re-create it in a state usable for this chapter can be downloaded from the Wrox support Website (wrox.com) or my personal support site at www.professionalsql.com. We have six distinct commands working here, covering a range of different things that we might do in a script. We’re using both system functions and local variables, the USE statement, INSERT statements, and both assignment and regular versions of the SELECT statement. They are all working in unison to accomplish one task — to insert complete orders into the database. The USE Statement 326 The USE statement sets the current database. This affects any place where we are making use of default values for the database portion of our fully qualified object name. In this particular example, we have not indicated what database the tables in our INSERT or SELECT statements are from, but, since we’ve included a USE statement prior to our INSERT and SELECT statements, they will use that database (in this case, Accounting). Without our USE statement, we would be at the mercy of whoever executes the script to make certain that the correct database was current when the script was executed. Don’t take this as meaning that you should always include a USE statement in your script — it depends on what the purpose of the script is. If your intent is to have a general-purpose script, then leaving out the USE statement might actually be helpful. Usually, if you are naming database-specific tables in your script (that is, non-system tables), then you want to use the USE command. I also find it very helpful if the script is meant to modify a specific database — as I’ve said in prior chapters, I can’t tell you how many times I’ve accidentally created a large number of tables in the master database that were intended for a user database.
Next we have a DECLARE statement to declares a variable. We've seen DECLARE statements used in a few scripts used earlier in the book, but let's visit them a bit more formally. Declaring Variables The DECLARE statement has a pretty simple syntax: DECLARE @ [= ][, @ [= ][, @ [= ]]] You can declare just one variable at a time, or several. It’s common to see people reuse the DECLARE statement with each variable they declare, rather than use the comma-separated method. It’s up to you, but no matter which method you choose, you must initialize the variable (using the "=" syntax) or the value of your variable will be NULL until you explicitly set it to some other value. In this case, we’ve declared a local variable called @ident as an integer. I've chosen not to initialize it as the whole purpose of this variable is to accept a value from another source. Technically, we could have gotten away without declaring this variable — instead, we could have chosen to just use @@IDENTITY directly. @@IDENTITY is a system function. It is always available, and supplies the last identity value that was assigned in the current connection. As with most system functions, you should make a habit of explicitly moving the value in @@IDENTITY to a local variable. That way, you’re sure that it won’t get changed accidentally. There was no danger of that in this case, but, as always, be consistent. Setting the Value in Your Variables Chapter 11: Writing Scripts and Batches I like to move a value I’m taking from a system function into my own variable. That way I can safely use the value and know that it’s being changed only when I change it. With the system function itself, you sometimes can’t be certain when it’s going to change because most system functions are not set by you, but by the system. That creates a situation where it would be very easy to have the system change a value at a time you weren’t expecting it, and wind up with the most dreaded of all computer terms: unpredictable results. Well, we now know how to declare our variables, but the question that follows is, “How do we change their values?” There are two ways to set the value in a variable. You can use a SELECT statement or a SET statement. Functionally, they work almost the same, except that a SELECT statement has the power to have the source value come from a column within the SELECT statement. So why have two ways of doing this? Actually, I still don’t know. After publishing four books that ask this very question, I figured someone would e-mail me and give me a good answer — they didn’t. Suffice to say that SET is now part of the ANSI/ISO standard, and that’s why it’s been put in there. However, I can’t find anything wrong with the same functionality in SELECT — even ANSI/ISO seems to think that it’s OK. I’m sure there’s a purpose in the redundancy, but what it is I can’t tell you. That said, there are some differences in the way they are used in practice. 327
- Page 313 and 314: Root Non-Leaf Level Leaf Level Figu
- Page 315 and 316: The CREATE INDEX Statement The CREA
- Page 317 and 318: FILLFACTOR When SQL Server first cr
- Page 319 and 320: works only if tempdb is on a separa
- Page 321 and 322: Secondary XML Indexes Chapter 9: SQ
- Page 323 and 324: occur, and that one or more non-lea
- Page 325 and 326: isn’t room on the page, SQL Serve
- Page 327 and 328: more administrator oriented and usu
- Page 329 and 330: The Database Engine Tuning Advisor
- Page 331 and 332: The output is far more self-describ
- Page 333 and 334: We use a FILLFACTOR when we need to
- Page 335: Chapter 9: SQL Server Storage and I
- Page 338 and 339: Chapter 10: Views The preceding syn
- Page 340 and 341: Chapter 10: Views 302 columns to a
- Page 342 and 343: Chapter 10: Views Try It Out Using
- Page 344 and 345: Chapter 10: Views 306 soh.SalesOrde
- 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: 11 Writing Scripts and Batches Whet
- 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 and 396: 3 8 More Than One Apart 2 2 Ends Wi
- Page 397 and 398: Now, I don’t know about you, but
- 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 [
Next we have a DECLARE statement to declares a variable. We've seen DECLARE statements used in a few<br />
scripts used earlier in the book, but let's visit them a bit more formally.<br />
Declaring Variables<br />
The DECLARE statement has a pretty simple syntax:<br />
DECLARE @ [= ][,<br />
@ [= ][,<br />
@ [= ]]]<br />
You can declare just one variable at a time, or several. It’s common to see people reuse the DECLARE<br />
statement with each variable they declare, rather than use the comma-separated method. It’s up to you,<br />
but no matter which method you choose, you must initialize the variable (using the "=" syntax) or the<br />
value of your variable will be NULL until you explicitly set it to some other value.<br />
In this case, we’ve declared a local variable called @ident as an integer. I've chosen not to initialize it as<br />
the whole purpose of this variable is to accept a value from another source. <strong>Tech</strong>nically, we could have<br />
gotten away without declaring this variable — instead, we could have chosen to just use @@IDENTITY<br />
directly. @@IDENTITY is a system function. It is always available, and supplies the last identity value that<br />
was assigned in the current connection. As with most system functions, you should make a habit of<br />
explicitly moving the value in @@IDENTITY to a local variable. That way, you’re sure that it won’t get<br />
changed accidentally. There was no danger of that in this case, but, as always, be consistent.<br />
Setting the Value in Your Variables<br />
Chapter 11: Writing Scripts and Batches<br />
I like to move a value I’m taking from a system function into my own variable. That<br />
way I can safely use the value and know that it’s being changed only when I change<br />
it. With the system function itself, you sometimes can’t be certain when it’s going to<br />
change because most system functions are not set by you, but by the system. That<br />
creates a situation where it would be very easy to have the system change a value at<br />
a time you weren’t expecting it, and wind up with the most dreaded of all computer<br />
terms: unpredictable results.<br />
Well, we now know how to declare our variables, but the question that follows is, “How do we change<br />
their values?” There are two ways to set the value in a variable. You can use a SELECT statement or a SET<br />
statement. Functionally, they work almost the same, except that a SELECT statement has the power to<br />
have the source value come from a column within the SELECT statement.<br />
So why have two ways of doing this? Actually, I still don’t know. After publishing four books that ask<br />
this very question, I figured someone would e-mail me and give me a good answer — they didn’t. Suffice<br />
to say that SET is now part of the ANSI/ISO standard, and that’s why it’s been put in there. However, I<br />
can’t find anything wrong with the same functionality in SELECT — even ANSI/ISO seems to think that<br />
it’s OK. I’m sure there’s a purpose in the redundancy, but what it is I can’t tell you. That said, there are<br />
some differences in the way they are used in practice.<br />
327