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

Microsoft SQL Server 2008 R2 Unleashed- P179 ppsx

10 111 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 303,34 KB

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

Nội dung

You can, however, execute dynamic SQL that creates the object: CREATE PROC create_other_proc AS EXEC ‘CREATE PROC get_au_lname AS SELECT au_lname from authors RETURN’ TIP If you are usin

Trang 1

Check the @@errorsystem function after each SQL statement, especially insert,

update, and delete, to verify that the statements executed successfully Return a

status code other than 0if a failure occurs

Be sure to comment your code so that when you or others have to maintain it, the

code is self-documenting

Consider using a source code management system, such as Microsoft Visual Studio

SourceSafe, CVS, or Subversion, to maintain versions of your stored procedure

source code

You should avoid using select *in your stored procedure queries If someone were to

add columns to or remove columns from a table, the stored procedure would generate a

different result set, which could cause errors with the applications

Whenever using INSERTstatements in stored procedures, you should always provide the

column list associated with the values being inserted This allows the procedure to

continue to work if the table is ever rebuilt with a different column order or additional

columns are added to the table Listing 44.1 demonstrates what happens if the column list

is not provided and a column is added to the referenced table

LISTING 44.1 Lack of Column List in INSERT Statement Causing Procedure to Fail

use bigpubs2008

go

IF EXISTS ( SELECT * FROM sys.procedures

WHERE schema_id = schema_id(‘dbo’) AND name = N’insert_publishers’) DROP PROCEDURE dbo.insert_publishers

GO

create proc insert_publishers @pub_id char(4),

@pub_name varchar(40),

@city varchar(20),

@state char(2),

@country varchar(30) as

INSERT INTO bigpubs2008.dbo.publishers

VALUES(@pub_id, @pub_name, @city, @state, @country)

if @@error = 0

print ‘New Publisher added’

go

exec insert_publishers ‘9950’, ‘Sams Publishing’, ‘Indianapolis’, ‘IN’, ‘USA’

go

New Publisher added

Trang 2

alter table publishers add street varchar(80) null

go

exec insert_publishers ‘9951’, ‘Pearson Education’, ‘Indianapolis’, ‘IN’, ‘USA’

go

Msg 213, Level 16, State 1, Procedure insert_publishers, Line 7

Insert Error: Column name or number of supplied values does not match table

definition.

A stored procedure cannot directly create schemas, views, triggers, defaults, rules,

aggre-gates, functions, or stored procedures You can, however, execute dynamic SQL that

creates the object:

CREATE PROC create_other_proc AS

EXEC (‘CREATE PROC get_au_lname AS

SELECT au_lname from authors

RETURN’)

TIP

If you are using dynamic SQL to create objects in stored procedures, be sure to qualify

each object with the name of the object schema if users other than the stored

proce-dure owner will be executing the stored proceproce-dure

You can create tables in stored procedures Generally, only temporary tables are created in

stored procedures Temporary tables created in stored procedures are dropped

automati-cally when the procedure terminates Global temporary tables, however, exist until the

connection that created them terminates

If you don’t qualify object names within a stored procedure, they default to the schema of

the stored procedure It is recommended that objects in stored procedures be qualified

with the appropriate schema name to avoid confusion

You cannot drop a table and re-create another table with the same name within the

proce-dure unless you use dynamic SQL to execute a string that creates the table

A stored procedure cannot issue the USEstatement to change the database context in

which it is running; the database context for execution is limited to a single database If

you need to reference an object in another database, you should qualify the object name

with the database name in your procedure code

Calling Stored Procedures from Transactions

Stored procedures can be called from within a transaction, and they can also initiate

transactions SQL Server notes the transaction nesting level, which is available from the

@@trancountfunction, before calling a stored procedure If the value of@@trancount

Trang 3

when the procedure returns is different from the value of@@trancountwhen it was

executed, SQL Server displays error message 266:Transaction count after EXECUTE

indicates that a COMMIT or ROLLBACK TRAN is missing This message indicates that

transaction nesting is out of balance Because a stored procedure does not abort the batch

on arollback transactionstatement, arollback transactionstatement inside the

procedure could result in a loss of data integrity if subsequent statements are executed

and committed

Arollback transactionstatement rolls back all statements to the outermost transaction,

including any work performed inside nested stored procedures that have not been fully

committed A commit tranwithin the stored procedure decreases the value of

@@trancountby only one Because the transaction is not fully committed until

@@trancountreturns to zero, the work can be completely rolled back at any time prior to

that Essentially, the nested transaction inside the stored procedure is largely ignored The

modifications within the procedure are committed or rolled back based on the final action

taken for the outermost transaction

To avoid transaction nesting issues, you need to develop a consistent error-handling

strat-egy for failed transactions or other errors that occur in transactions within your stored

procedures and implement that strategy consistently across all procedures and

applica-tions Within stored procedures that might be nested, you need to check whether the

procedure is already being called from within a transaction before issuing anotherbegin

transtatement If a transaction is already active, you can issue asave transtatement so

that the procedure can roll back only the work that it has performed and allow the calling

procedure that initiated the transaction to determine whether to continue or abort the

overall transaction

To maintain transaction integrity when calling procedures that involve transactions,

follow these guidelines:

Make no net change to @@trancountwithin your stored procedures

Issue a begin tranonly if no transaction is already active

Set a savepoint if a transaction is already active so that a partial rollback can be

performed within the stored procedure

Implement appropriate error handling and return an error status code if something

goes wrong and a rollback occurs

Issue a commit tranonly if the stored procedure issued the begin transtatement

Listing 44.2 provides a template for a stored procedure that can ensure transactional

integrity whether it is run as part of an ongoing transaction or independently

LISTING 44.2 Template Code for a Stored Procedure That Can Run as Part of a Transaction or

Run as Its Own Transaction

/* proc to demonstrate no net change to @@trancount

** but rolls back changes within the proc

** VERY IMPORTANT: return an error code

Trang 4

** to tell the calling procedure rollback occurred */

create proc ptran1

as

declare @trncnt int

select @trncnt = @@trancount — save @@trancount value

if @trncnt = 0 — transaction has not begun

begin tran ptran1 — begin tran increments nest level to 1

else — already in a transaction

save tran ptran1 — save tran doesn’t increment nest level

/* do some processing */

if (@@error != 0) — check for error condition

begin

rollback tran ptran1 — rollback to savepoint, or begin tran

return 25 — return error code indicating rollback

end

/* more processing if required */

if @trncnt = 0 — this proc issued begin tran

commit tran ptran1 — commit tran, decrement @@trancount to 0

— commit not required with save tran return 0 /* successful return */

Listing 44.3 provides a template for the calling batch that might execute the stored

proce-dure shown in Listing 44.2 The main problem you need to solve is handling return codes

properly and responding with the correct transaction handling

LISTING 44.3 Template Code for a Calling Batch or Stored Procedure That Might Execute a

Stored Procedure Built with the Template in Listing 44.2

/* Retrieve status code to determine if proc was successful */

declare @status_val int, @trncnt int

select @trncnt = @@trancount — save @@trancount value

if @trncnt = 0 — transaction has not begun

begin tran t1 — begin tran increments nest level to 1

Trang 5

else — otherwise, already in a transaction

save tran t1 — save tran doesn’t increment nest level

/* do some processing if required */

if (@@error != 0) — or other error condition

begin

rollback tran t1 — rollback to savepoint,or begin tran

return — and exit batch/procedure

end

execute @status_val = ptran1 —exec procedure, begin nesting

if @status_val = 25 — if proc performed rollback

begin — determine whether to rollback or continue

rollback tran t1

return

end

/* more processing if required */

if @trncnt = 0 — this proc/batch issued begin tran

commit tran t1 — commit tran, decrement @@trancount to 0

return — commit not required with save tran

Handling Errors in Stored Procedures

SQL Server 2008 provides the TRY CATCHconstruct, which you can use within your

T-SQL stored procedures to provide a more graceful mechanism for exception handling than

was available in previous versions of SQL Server by checking@@ERROR(and often the use of

GOTOstatements) after each SQL statement

ATRY CATCHconstruct consists of two parts: a TRYblock and a CATCHblock When an

error condition is detected in a T-SQL statement inside a TRYblock, control is immediately

passed to a CATCHblock, where the error is processed T-SQL statements in the TRYblock

that follow the statement that generated the error are not executed

If an error occurs and processing is passed to the CATCHblock, after the statements in the

CATCHblock are executed, control is then transferred to the first T-SQL statement that

follows the END CATCHstatement If there are no errors inside the TRYblock, control is

passed to the statement immediately after the associated END CATCHstatement, essentially

skipping over the statements in the CATCHblock

ATRYis initiated with the BEGIN TRYstatement and ended with the END TRYstatement

and can consist of one or more T-SQL statements between the BEGIN TRYandEND TRY

statements The TRYblock must be followed immediately by a CATCHblock A CATCHblock

Trang 6

is indicated with the BEGIN CATCHstatement and ended with the END CATCHstatement and

can consist of one or more SQL statements In SQL Server, each TRYblock can be

associ-ated with only one CATCHblock

The syntax of the TRY CATCHconstruct is as follows:

BEGIN TRY

one_or_more_sql_statements

END TRY

BEGIN CATCH

one_or_more_sql_statements

END CATCH

When in a CATCHblock, you can use the following error functions to capture information

about the error that invoked the CATCHblock:

error occurred

Unlike@@error, which is reset by each statement that is executed, the error information

retrieved by the error functions remains constant anywhere within the scope of the CATCH

block of a TRY CATCHconstruct Error functions can also be referenced inside a stored

procedure and can be used to retrieve error information when the stored procedure is

executed within a CATCHblock This allows you to modularize the error handling into a

single procedure so you do not have to repeat the error-handling code in every CATCH

block Listing 44.4 shows an example of an error-handling procedure that you can use in

yourCATCHblocks

LISTING 44.4 An Example of a Standard Error-Handling Procedure

create proc dbo.error_handler

as

begin

Declare @errnum int,

@severity int,

@errstate int,

@proc nvarchar(126),

@line int,

@message nvarchar(4000)

capture the error information that caused the CATCH block to be invoked

Trang 7

SELECT @errnum = ERROR_NUMBER(),

@severity = ERROR_SEVERITY(),

@errstate = ERROR_STATE(),

@proc = ERROR_PROCEDURE(),

@line = ERROR_LINE(),

@message = ERROR_MESSAGE()

raise an error message with information on the error

RAISERROR (‘Failed to add new publisher for the following reason:

Error: %d, Severity: %d, State: %d, in proc %s at line %d, Message: “%s”’,

16, 1, @errnum, @severity, @errstate, @proc, @line, @message) Return

end

Listing 44.5 provides an example of the TRY CATCHconstruct in a stored procedure,

modifying the insert_publishersprocedure created in Listing 44.1 Note that this CATCH

block uses the dbo.error_handlerprocedure defined in Listing 44.4

LISTING 44.5 Using a TRY CATCH Construct for Error Handling in a Stored Procedure

use bigpubs2008

go

alter proc insert_publishers @pub_id char(4),

@pub_name varchar(40),

@city varchar(20),

@state char(2),

@country varchar(30) as

BEGIN TRY

INSERT INTO bigpubs2008.dbo.publishers

(pub_id, pub_name, city, state, country)

VALUES(@pub_id, @pub_name, @city, @state, @country)

if no error occurs, we should see this print statement

print ‘New Publisher added’

END TRY

BEGIN CATCH

invoke the error_handler procedure

exec error_handler

return a non-zero status code

RETURN -101

END CATCH

if successful execution, return 0

RETURN 0

go

exec insert_publishers ‘9951’, ‘Pearson Education’, ‘Indianapolis’, ‘IN’, ‘USA’

Trang 8

exec insert_publishers ‘9950’, ‘Sams Publishing’, ‘Indianapolis’, ‘IN’, ‘USA’

go

New Publisher added

Msg 50000, Level 16, State 1, Procedure insert_publishers, Line 18

Failed to add new publisher for the following reason:

Error: 2627, Severity: 14, State: 1, in proc insert_publishers at line 8,

Message: “Violation of PRIMARY KEY constraint ‘UPKCL_pubind’ Cannot insert

duplicate key in object ‘dbo.publishers’.”

If you want to capture and handle any errors that may occur within a CATCHblock, you

can incorporate another TRY CATCHblock within the CATCHblock itself

Also note that some errors with severity 20 or higher that cause SQL Server to close the

user connection cannot be handled by theTRY CATCHconstruct However, severity level

20 or higher errors that do not result in the connection being closed are captured and

handled by theCATCHblock Any errors with a severity level of 10 or less are considered

warnings or informational messages and not really errors and thus are not handled by the

TRY CATCHconstruct Also, any compile errors (such as syntax errors) or object name

resolution errors that happen during deferred name resolution also do not invoke aCATCH

block These errors are returned to the application or batch that called the

error-generat-ing routine

Using Source Code Control with Stored Procedures

When you can, it’s generally a good idea to use source code control for your stored

proce-dure scripts Stored proceproce-dures are as much a part of an application as the application

code itself and should be treated as such When using source code control, you can link

versions of your procedures and other object creation scripts with specific versions of

your applications Using source code control systems also provides a great way to keep

track of the changes to your stored procedures and other object creation scripts, enabling

you to go back to a previous version if the modifications lead to problems with the

appli-cations or data

SQL Server Management Studio (SSMS) provides a feature similar to Visual Studio that lets

you organize your SQL scripts into solutions and projects A project is a collection of one or

more script files stored in the Windows file system, usually in a folder with the same

name as the project A solution is a collection of one or more projects.

In addition to providing a way to manage and organize your scripts, SSMS can also

inte-grate with source code control software if the source code control system provides a

compatible plug-in If you are using Visual Studio, it’s likely that you are also using Visual

SourceSafe Visual SourceSafe provides a one-to-one mapping between SSMS projects and

Visual SourceSafe projects After you create an SSMS solution, you can check the entire

SSMS solution into Visual SourceSafe and then check out individual script files or projects

Trang 9

FIGURE 44.1 Creating a new project/solution and adding it to source control

You can also specify that a solution be added to source code control when you create a

new solution In SSMS, you select File, New and then select New Project In the New

Project dialog, you can specify the name for the project and solution, and you can also

specify whether to add the solution to source code control, as shown in Figure 44.1

When you add a solution to Visual SourceSafe, it prompts you for the login ID and

pass-word to use to access Visual SourceSafe After you provide that information, Visual

SourceSafe then prompts you for the Visual SourceSafe project to add the SMSS project to,

or it allows you to create a new project in Visual SourceSafe

Within a project, you can specify the database connection(s) for the project and add SQL

script files to the Queriesfolder After creating a new script file, you can add it into the

source code control system by right-clicking the script file in the Solutions Explorer and

selecting Check In (see Figure 44.2)

After you check in a script file, you can right-click the file and perform source code

control tasks such as checking out the script for editing, getting the current version,

comparing versions, and viewing the check-in history If you check out the script for

editing, you can then open it in a new query window, where you can make changes to the

script and then execute it in the database When you are satisfied with the changes, you

can check the new version back into the source code control system

For more information on working with solutions and projects in SSMS, see Chapter 4,

“SQL Server Management Studio.”

Trang 10

FIGURE 44.2 Checking in a new script file

Using Cursors in Stored Procedures

When using cursors in stored procedures in SQL Server, you need to be aware of the

scope of the cursor and how it can be accessed within calling or called procedures

Cursors in SQL Server can be declared as local or global A global cursor defined in a

stored procedure is available until it is deallocated or when the connection closes A local

cursor goes out of scope when the stored procedure that declared it terminates or the

procedure scope changes

If neither the GLOBALnorLOCALoption is specified when the cursor is declared in a stored

procedure, the default cursor type is determined by the database option CURSOR_DEFAULT,

which you set with the ALTER DATABASEstatement The default value for the option

is_local_cursor_defaultisFALSE, which defaults cursors as global, to match the

behav-ior of earlier versions of SQL Server If this value in the sys.databasescatalog view is set

toTRUE, T-SQL cursors default to local cursors

TIP

If neither GLOBALnorLOCALis specified, the default scope setting for cursors in SQL

Server 2008 is determined by the Default to Local Cursor database option This option

currently defaults to OFFto provide backward compatibility with versions of SQL Server

prior to 7.0, in which all cursors were global This default setting might change in

future versions, so it is recommended that you explicitly specify the LOCALorGLOBAL

option when declaring your cursors so your code will not be affected by changes to the

default setting

Ngày đăng: 05/07/2014, 02:20

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

  • Đang cập nhật ...

TÀI LIỆU LIÊN QUAN