1. Trang chủ
  2. » Công Nghệ Thông Tin

Hướng dẫn học Microsoft SQL Server 2008 part 61 pptx

10 422 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 621,69 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

These comments are useful for commenting out a block of lines such as a code header or large test query: /* Order table Insert Trigger Paul Nielsen ver 1.0 July 21, 2006 Logic: etc.. New

Trang 1

■ An application can submit a T-SQL batch using ADO or ODBC for execution.

■ A SQL script may be executed by running the SQLCMD command-line utility and passing the SQL script file as a parameter

■ The SQLCMD utility has several parameters and may be configured to meet nearly any command-line need

T-SQL formatting

Throughout this book, T-SQL code has been formatted for readability; this section specifies the details of

formatting T-SQL code

Statement termination

The ANSI SQL standard is to place a semicolon (;) at the end of each command in order to terminate it

When programming T-SQL, the semicolon is optional Most other database products (including Access)

do require semicolons

There are a few rules about using the semicolon:

■ Don’t place one after anEND TRY

■ Don’t place one after anIForWHILEcondition

■ You must place one before any CTE

■ A statement terminator is required following aMERGEcommand

Best Practice

As a best practice and for improved readability, I recommend using the semicolon In future versions of

SQL Server this may become a requirement, so making the change now may pay off later

Line continuation

T-SQL commands, by their nature, tend to be long I have written production queries with multiple

joins and subqueries that were a few pages long I like that T-SQL ignores spaces and end-of-line

returns This smart feature means that long lines can be continued without a special line-continuation

character, which makes T-SQL code significantly more readable

Comments

T-SQL accepts both simple comments and bracketed comments within the same batch The simple

comment begins with two hyphens and concludes with an end-of-line:

This is a simple comment Simple comments may be embedded within a single SQL command:

Trang 2

SELECT FirstName, LastName selects the columns

FROM Persons the source table

WHERE LastName LIKE ‘Hal%’; the row restriction

Management Studio’s Query Editor can apply or remove simple comments to all selected lines Select

either Edit➪ Advanced ➪ Comment Selection (Ctrl+K, Ctrl+C) or Edit ➪ Advanced ➪ Uncomment

Selection (Ctrl+K, Ctrl+U), respectively

Bracketed comments begin with/*and conclude with*/ These comments are useful for commenting

out a block of lines such as a code header or large test query:

/*

Order table Insert Trigger

Paul Nielsen

ver 1.0 July 21, 2006

Logic: etc

ver 1.1: July 31, 2006, added xyz

*/

A benefit of bracketed comments is that a large multi-line query within the comments may be selected

and executed without altering the comments

A GO batch terminator inside a bracketed comment block will terminate the batch, and the

statements after the GO will be executed as a new non-commented batch.

Variables

Every language requires variables to temporarily store values in memory T-SQL variables are created

with theDECLAREcommand TheDECLAREcommand is followed by the variable name and data type

The available data types are similar to those used to create tables, with the addition of thetableand

cursor The deprecatedtext,ntext, andimagedata types are only available for table columns, and

not for variables Multiple comma-separated variables can be declared with a singleDECLAREcommand

Variable default and scope

The scope, or application and duration, of the variable extends only to the current batch Newly

declared variables default toNULLand must be initialized if you want them to have a value in an

expression Remember that null added with a value yields null

New for SQL Server 2008 is the ability to initialize a variable to a value while declaring it, which saves

an extra line of code:

DECLARE @x INT = 0;

The following script creates two test variables and demonstrates their initial value and scope The entire

script is a single execution, even though it’s technically two batches (separated by aGO), so the results

of the threeSELECTstatements appear at the conclusion of the script:

Trang 3

DECLARE @Test INT ,

@TestTwo NVARCHAR(25);

SELECT @Test, @TestTwo;

SET @Test = 1;

SET @TestTwo = ‘a value’;

SELECT @Test, @TestTwo ;

GO

SELECT @Test AS BatchTwo, @TestTwo;

Result of the entire script:

-

(1 row(s) affected)

-

(1 row(s) affected) Msg 137, Level 15, State 2, Line 2 Must declare the scalar variable "@Test"

The firstSELECTreturns twoNULLvalues After the variables have been initialized, they properly

return the sample values When the batch concludes (due to theGOterminator), so do the variables

Error message 137 is the result of the finalSELECTstatement

Variables are local in scope and do not extend to other batches or called stored procedures

Using the set and select commands

Both theSETcommand and theSELECTcommand can assign the value of an expression to a variable

The main difference between the two is that aSELECTcan retrieve data from a data source (e.g., table,

subquery, or view) and can include the otherSELECTclauses as well (e.g.,FROM, WHERE), whereas a

SETis limited to retrieving data from expressions BothSETandSELECTcan include functions Use

the simplerSETcommand when you only need to assign a function result or constant to a variable and

don’t need the Query Optimizer to consider a data source

A detailed exception to the preceding paragraph is when aSETcommand uses a scalar subquery that

accesses a data source This is a best practice if you want to ensure that the variable is set toNULLif no

rows qualify, and that you get an error if more than one row qualifies

Of course, aSELECTstatement may retrieve multiple columns Each column may be assigned to a

vari-able If theSELECTstatement retrieves multiple rows, then the values from the last row are stored in

the variables No error will be reported

Trang 4

The following SQL batch creates two variables and initializes one of them TheSELECTstatement will

retrieve 32 rows, ordered byPersonID ThePersonIDand theLastNameof the last person returned

by theSELECTwill be stored in the variables:

USE Family;

DECLARE @TempID INT,

@TempLastName VARCHAR(25);

SET @TempID = 99;

SELECT

@TempID = PersonID,

@TempLastName = LastName

FROM Person

ORDER BY PersonID;

SELECT @TempID, @TempLastName;

Result:

-

-Campbell

The preceding code demonstrates a common coding mistake Never use a SELECT to

popu-late a variable unless you’re sure that it will return only a single row.

If no rows are returned from theSELECTstatement, theSELECTdoes not affect the variables In the

following query, there is no person with a PersonIDof 100, so theSELECTstatement does not affect

either variable:

DECLARE @TempID INT,

@TempLastName VARCHAR(25);

SET @TempID = 99;

SELECT @TempID = PersonID,

@TempLastName = LastName

FROM Person

WHERE PersonID = 100

ORDER BY PersonID;

SELECT @TempID, @TempLastName;

The finalSELECTstatement reports the value of @TempIDand@TempLastName, and indeed they are

still99andNULL, respectively The firstSELECTdid not alter its value:

-

-NULL

Incrementing variables

T-SQL finally has the increment variable feature, which saves a few keystrokes when coding and

certainly looks cleaner and more modern

The basic idea is that an operation and equals sign will perform that function on the variable For

example, the code

Trang 5

SET @x += 5;

is the logical equivalent of

SET @x = @x + 5 The next short script walks through addition, subtraction, and multiplication using the new variable

increment feature:

DECLARE @x INT = 1 SET @x += 5

SELECT @x SET @x -=3 SELECT @x SET @x *= 2 SELECT @x Result (of whole batch):

-6

-3

-6

Conditional select

Because theSELECTstatement includes aWHEREclause, the following syntax works well, although

those not familiar with it may be confused:

SELECT @Variable = expression WHERE BooleanExpression;

TheWHEREclause functions as a conditionalIFstatement If the Boolean expression is true, then the

SELECTtakes place If not, theSELECTis performed but the@Variableis not altered in any way

because theSELECTcommand has no effect

Using variables within SQL queries

One of my favorite features of T-SQL is that variables may be used with SQL queries without having to

build any complex dynamic SQL strings to concatenate the variables into the code Dynamic SQL still

has its place, but the single value can simply be modified with a variable

Anywhere an expression can be used within a SQL query, a variable may be used in its place The

following code demonstrates using a variable in aWHEREclause:

Trang 6

USE OBXKites;

DECLARE @ProductCode CHAR(10);

SET @Code = ‘1001’;

SELECT ProductName

FROM Product

WHERE Code = @ProductCode;

Result:

Name

-Basic Box Kite 21 inch

Debugging T-SQL

When a syntax error is found, the Query Editor will display the error and the line number of the error

within the batch Double-clicking on the error message will place the cursor near the offending line

Often the error won’t occur at the exact word that is reported as the error The error location reported simply

reflects how far SQL Server’s parser got before it detected the error Usually the actual error is somewhere

just before or after the reported error Nevertheless, the error messages are generally close

SQL Server 2008 brings back the T-SQL debugger, which is great for debugging variables, and flow of

control, but it can’t help when debugging a query

Most of the debugging I need to do involves checking the contents of a temp table or table variable to see

the output of a query Inserting a SELECT command and running the batch up to that SELECT command

works well for my purposes

My other debugging technique is to double-check the source data Seriously More than half the time when

I don’t get what I expect from a T-SQL query or batch, the problem is not the code, but the data SQL is

basically asking a question of the data and returning the result If the data isn’t what you thought it was, then

neither will the answer be what you expected This is why I’m such a stickler for unit testing using a small

set of sample data

Multiple assignment variables

A multiple assignment variable, sometimes called an aggregate concatenation, is a fascinating method that

appends a variable to itself using aSELECTstatement and a subquery

This section demonstrates a real-world use of multiple assignment variables, but because it’s an unusual

use of theSELECTstatement, here it is in its basic form:

SELECT @variable = @variable + d.column

FROM datasource;

Trang 7

Each row from the derived table is appended to the variable, changing the vertical column in the

under-lying table into a horizontal list

This type of data retrieval is quite common Often a vertical list of values is better reported as a single

comma-delimited horizontal list than as a subreport or another subheading level several inches long A

short horizontal list is more readable and saves space

The following example builds a list of departments in theAdventureWorks2008sample database

from theHumanResources.Departmenttable:

USE AdventureWorks2008;

Declare @MAV VARCHAR(max) SELECT @MAV = Coalesce(@MAV + ‘, ’ + Name, Name) FROM (select name from HumanResources.Department) D order by name

Select @MAV Result:

-Changed Name, Document Control, Engineering, Executive, Facilities and Maintenance, Finance, Human Resources, Information Services, Marketing, Production, Production Control, Purchasing, Quality Assurance, Research and Development, Sales, Shipping and Receiving

The problem with multiple assignment variables is that Microsoft is vague about their behavior The

order of the denormalized data isn’t guaranteed, but queries do seem to respond to theORDER BY

clause It’s not documented in BOL but it has been documented in MSKB article Q287515 It performs

very well, but I’m cautious about using it when the result is order dependent

The multiple assignment variable may be used with an UPDATE command to merge multiple rows during the update For more details, turn back to Chapter 12, ‘‘Aggregating Data.’’

An alternate method of denormalizing a list is the XML PATH method:

Select [text()] = Name + ‘,’

FROM (select distinct name from HumanResources.Department) D order by Name

FOR XML PATH(’’)

For more details on XML, see Chapter 18, ‘‘Manipulating XML Data.’’

Procedural Flow

At first glance, it would appear that T-SQL is weak in procedural-flow options While it’s less rich than

some other languages, it suffices The data-handling Boolean extensions — such asEXISTS,IN, and

CASE— offset the limitations of IFandWHILE

Trang 8

This is your grandfather’sIF The T-SQLIFcommand determines the execution of only the next single

statement — oneIF, one command In addition, there’s noTHENand noEND IFcommand to

termi-nate theIFblock:

IF Condition

Statement;

In the following script, theIFcondition should return a false, preventing the next command from

executing:

IF 1 = 0

PRINT ‘Line One’;

PRINT ‘Line Two’;

Result:

Line Two

The IF statement is not followed by a semicolon; in fact, a semicolon will cause an error.

That’s because the IF statement is actually a prefix for the following statement; the two

are compiled as a single statement.

Begin/end

AnIFcommand that can control only a single command is less than useful However, aBEGIN/END

block can make multiple commands appear to theIFcommand as the next single command:

IF Condition

Begin;

Multiple lines;

End;

I confess: Early one dreary morning a couple of years ago, I spent an hour trying to debug a stored

pro-cedure that always raised the same error no matter what I tried, only to realize that I had omitted the

BEGINandEND, causing theRAISERRORto execute regardless of the actual error condition It’s an easy

mistake to make

If exists()

While theIFcommand may seem limited, the condition clause can include several powerful SQL

features similar to aWHEREclause, such as IF EXISTS()andIF IN()

TheIF EXISTS()structure uses the presence of any rows returned from a SQLSELECTstatement

as a condition Because it looks for any row, theSELECTstatement should select all columns (*) This

method is faster than checking an@@rowcount >0condition, because the total number of rows isn’t

required As soon as a single row satisfies theIF EXISTS(), the query can move on

Trang 9

The following example script uses theIF EXISTS()technique to process orders only if any open

orders exist:

USE OBXKITES;

IF EXISTS(SELECT * FROM [ORDER] WHERE Closed = 0)

BEGIN;

PRINT ‘Process Orders’;

END;

There is effectively no difference betweenSELECT *or selecting a column However, selecting all

columns enables SQL Server to select the best column from an index and might, in some situations, be

slightly faster

If/else

The optionalELSEcommand defines code that is executed only when theIFcondition is false Like

IF,ELSEcontrols only the next single command orBEGIN/ENDblock:

IF Condition

Single line or begin/end block of code;

ELSE

Single line or begin/end block of code;

While

TheWHILEcommand is used to loop through code while a condition is still true Just like theIF

com-mand, theWHILEcommand determines the execution of only the following single T-SQL command To

control a full block of commands,BEGIN/ENDis used

Some looping methods differ in the timing of the conditional test The T-SQLWHILEworks in the

following order:

1 TheWHILEcommand tests the condition If the condition is true,WHILEexecutes the follow-ing command or block of code; if not, it skips the followfollow-ing command or block of code and moves on

2 Once the following command or block of code is complete, flow of control is returned to the

WHILEcommand

The following short script demonstrates using theWHILEcommand to perform a loop:

DECLARE @Temp INT;

SET @Temp = 0;

WHILE @Temp < 3 BEGIN;

PRINT ‘tested condition’ + STR(@Temp);

SET @Temp = @Temp + 1;

END;

Trang 10

tested condition 0

tested condition 1

tested condition 2

TheCONTINUEandBREAKcommands enhance theWHILEcommand for more complex loops The

CONTINUEcommand immediately jumps back to theWHILEcommand The condition is tested as

normal

TheBREAKcommand immediately exits the loop and continues with the script as if theWHILE

condition were false The following pseudocode (not intended to actually run) demonstrates theBREAK

command:

CREATE PROCEDURE MyLife()

AS

WHILE Not @@Eyes2blurry = 1

BEGIN;

EXEC Eat;

INSERT INTO Book(Words)

FROM Brain(Words)

WHERE Brain.Thoughts

IN(’Make sense’, ‘Good Code’, ‘Best Practice’);

IF @SciFi_Eureka = ‘On’

BREAK;

END;

Goto

Before you associate the T-SQLGOTOcommand with bad memories of 1970s-style spaghetti-BASIC, this

GOTOcommand is limited to jumping to a label within the same batch or procedure, and is rarely used

for anything other than jumping to an error handler at the close of the batch or procedure

The label is created by placing a colon after the label name:

LabelName:

The following code sample uses theGOTOcommand to branch to theErrorHandler:label, bypassing

the‘more code’:

GOTO ErrorHandler;

Print ‘more code’;

ErrorHandler:

Print ‘Logging the error’;

Result:

Logging the error

Ngày đăng: 04/07/2014, 09:20

TỪ KHÓA LIÊN QUAN