Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every...

43
Advanced SQL Programming and Optimization Everything you wanted to know about Stored Procedures!

Transcript of Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every...

Page 1: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Advanced SQL Programming and Optimization

Everything you wanted to know about Stored Procedures!

Page 2: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

About Soaring Eagle Since 1997, Soaring Eagle Consulting has been helping enterprise clients improve their overall system performance at the database tier, arguably the most volatile and critical component of distributed application architecture. Our clients range in size from fledgling startups through Fortune 100 companies and leading financial institutions. Soaring Eagle has been a leader in managed services, database architecture, performance and tuning databases, while promoting mentoring and training all over the world for over a decade and a half. Many of our employees, and partners have written books, speak at seminars about leading edge technologies. We have expertise in all business tiers, financial; health, manufacturing, government agencies and many ecommerce businesses. Whatever your business needs are we can help improve performance!

Consulting • Performance & Tuning • Data Performance

Management • Emergency Triage • Performance & Security

Audits • Staff Augmentation • Project management • Database architecture • Scalability assessment and

planning

Training • Onsite/Web based

• Microsoft • Sybase • Oracle • APM • Six Sigma

Software • Application Performance

Management • Database performance

management • Database Security

Managed Services • Remote Database

Management • Performance management • Emergency db Service • Proactive mitigation • Problem notification • Problem resolution

2- 43 © Soaring Eagle Consulting 8/19/2013

Page 3: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Acknowledgements

• Microsoft SQL server, SSMS are trademarks of Microsoft Inc.

• This presentation is copyrighted by Soaring Eagle Consulting, August 7, 2013

• This presentation is not for re-sale

• This presentation shall not be used, modified, or redistributed without express written consent of Soaring Eagle Consulting, Inc.

• Solarwinds Ignite is registered trademark of Solarwinds Inc.

3- 43 © Soaring Eagle Consulting 8/19/2013

Page 4: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Topics

• Review stored procedure coding recommendations

• Define appropriate error handling, return status and parameter techniques

• Understand compilation issues

• Examine performance factors

4- 43 © Soaring Eagle Consulting 8/19/2013

Page 5: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

SP Coding Standards and Conventions

• Follow normal standard coding guidelines as you would for any programming language

• Use explanatory comments

– Use indentation to improve readability

– Develop structured methods of handling errors within stored procedures

– Develop a method for maintaining versions of stored procedure source code

5- 43 © Soaring Eagle Consulting 8/19/2013

Page 6: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Structured Error Handling in Stored Procedures

• There are two valid options:

– Try…catch blocks

– Check for errors after every SQL statements take appropriate error handling steps

• Check @@error value

• Always use the return statement with status codes when procedure encounters an error

• Always check the return status of called stored procedures

• Set up defaults for all parameters and perform parameter checks at the beginning of procedure

6- 43 © Soaring Eagle Consulting 8/19/2013

Page 7: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Returning Procedure Status

• Every stored procedure automatically returns an integer status value

– Zero is returned on successful completion

– -1 through -99 are returned for SQL Server detected errors

• Use a return statement to specify a return value greater than or equal to 0 or less than -99

• The calling program can set up a local variable to receive and check the return status

7- 43 © Soaring Eagle Consulting 8/19/2013

Page 8: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Returning Procedure Status (Cont’d)

create proc procedure_name

[ (parm_name datatype = default_value [output]

[, ... ] ) ]

as

SQL Statements

return [integer_status_value]

[execute] [@status_var = ] procedure_name

[[parm_name = ] expression [output] [, … ]

8- 43 © Soaring Eagle Consulting 8/19/2013

Page 9: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Procedure Creation

/* procedure sets an error status on error */

create proc titles_for_a_pub

(@pub_name varchar(40) = null ) as

if @pub_name = null

return 15

if not exists

(select * from publishers

where pub_name = @pub_name)

return -101

select title from publishers p join titles t

on p.pub_id = t.pub_id

where pub_name = @pub_name

return 0

9- 43 © Soaring Eagle Consulting 8/19/2013

Page 10: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Return Status Example

Procedure Usage

/* check for status and report errors */

declare @status int

exec @status = titles_for_a_pub 'New Age Books'

if @status = 15

print 'Invalid Syntax'

else if @status = -101

print 'No publisher by that name found'

10- 43 © Soaring Eagle Consulting 8/19/2013

Page 11: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

SQL Server Status Codes

Following is a list of return status codes currently in use by SQL Server

Status Code Meaning

0 Successful return -1 Missing object referenced -2 Datatype mismatch error -3 Process chosen as deadlock victim

-4 Permission error -5 Syntax error -6 Miscellaneous user error -7 Resource error, such as out of space

-8 Non-fatal internal problem (bug) -9 System limit reached

-10 Fatal internal inconsistency (bug) -11 Fatal internal inconsistency (bug) -12 Table or index corrupted -13 Database corrupt -14 Hardware error

11- 43 © Soaring Eagle Consulting 8/19/2013

Page 12: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Default Parameter Values

• Stored procedure parameters can be assigned default values if no value is supplied during execution

• You can improve your stored procedure code by defining defaults for all parameters

create proc procedure_name

(parameter_name datatype = default_value

[,...])

as

SQL Statements

[return [status_value]]

12- 43 © Soaring Eagle Consulting 8/19/2013

Page 13: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Default Parameter Values (Cont’d)

Procedure Creation Example

/* check for a pub_name before executing query */

create proc titles_for_a_pub

(@pub_name varchar(40) = null)

as

if @pub_name = null

begin

print ‘Pass in the pub_name as a parameter’

return

end

select t.title from publishers p join titles t

on p.pub_id = t.pub_id

where pub_name like @pub_name + ‘%’

return

13- 43 © Soaring Eagle Consulting 8/19/2013

Page 14: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Executing with Parameters

• At execution time, parameters may be specified by position or by name

• If passed by name, parameters can be passed in any order

[exec[ute]] procedure_name

[[@parm_name = ]expression] [, ... ]

14- 43 © Soaring Eagle Consulting 8/19/2013

Page 15: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Executing with Parameters (Cont’d)

create proc myproc (@val1 int, @val2 int, @val3 int) as ... go /* parameters passed by position here */ exec myproc 10,20,15 /* parameter passed by name here */ exec myproc @val2 = 20, @val1 = 10, @val3 = 15

Procedure Creation Example

15- 43 © Soaring Eagle Consulting 8/19/2013

Page 16: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Notes on Parameters

• Once you have started passing parameters by name, all subsequent parameters must be passed by name

• If you want to skip any parameters and have them take default values, you will need to pass parameters by name unless they are the last parameter(s) in the procedure

• In programming environments, passing parameters by name is more flexible and self-documenting than passing parameters by position

16- 43 © Soaring Eagle Consulting 8/19/2013

Page 17: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Stored Procedure Recompilation

The SQL Server optimizer caches a query plan based on parameters passed

at the time the query plan was generated.

• This procedure could conceivably generate two distinctly different query plans based upon the values supplied for @low and @high

• Consider the following procedure

create proc range_value (@low int, @high int)

as

select sum (total_sales) from titles

where price between @low and @high

return

17- 43 © Soaring Eagle Consulting 8/19/2013

Page 18: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Stored Procedure Recompilation (Cont’d)

• Subsequent executions of the procedure will use any available procedure query plan

• To guarantee the proper query plan for each execution, create the stored procedure with the “with recompile” option

create proc range_value (@low int, @high int)

with recompile

as

select sum (price) from titles

where price between @low and @high

return

18- 43 © Soaring Eagle Consulting 8/19/2013

Page 19: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Stored Procedure Recompilation (Cont’d)

• To generate a new query plan for a specific execution use the “with recompile” option when executing the procedure

• To generate new query plans for all procedures dependent on a specific table, execute

execute range_value 10, 200 with recompile

sp_recompile table_name

19- 43 © Soaring Eagle Consulting 8/19/2013

Page 20: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Recompiling Stored Procedures

• Creating the proc with the “with recompile” option causes a new query plan to be generated for each execution. This creates a lot of overhead with the optimizer

• The effect of using “with recompile” on stored procedure execution will generate a new query plan for the current execution, but does not affect any existing query plans in cache

– The query plan used for subsequent executions is indeterminate

20- 43 © Soaring Eagle Consulting 8/19/2013

Page 21: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Recompiling Stored Procedures

• Procedure query plans are not automatically recompiled if indexes are added or statistics are updated

– Run sp_recompile on the affected table • If indexes associated with the query plan are dropped, all

procedure query plans will be automatically recompiled

• The only ways to flush all existing query plans from cache are to:

– Drop and recreate the stored procedure

– Run dbcc freeproccache

• (clears ALL procedure cache)

– Cycle the SQL Server

21- 43 © Soaring Eagle Consulting 8/19/2013

Page 22: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Other Compilation Issues

create proc get_data (@flag tinyint, @value int)

as

if @flag = 1

begin

select * from titles where price > @value

exec get_titles @value

end

else

begin

select * from salesdetail where qty < @value

exec get_sales_detail @value

end

22- 43 © Soaring Eagle Consulting 8/19/2013

Page 23: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Alternatives to Recompile (Cont’d)

• On first execution, the optimizer will generate a query plan for ALL select statements based upon the passed in parameters, regardless of the conditional branching

Note: This could result in the wrong query plan being generated for one of the select statements

Recommendation:

– If this type of stored procedure must be written, have it call multiple stored procedures (as opposed to creating it with recompile)

23- 43 © Soaring Eagle Consulting 8/19/2013

Page 24: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Calling Stored Procedures from Transactions

• A rollback inside a stored procedure can lead to unexpected results because it does not abort the batch

/* transaction in the batch */

begin tran

insert tally values (1)

if @@error != 0

rollback tran

else

execute the_proc

insert tally values (3)

if @@error != 0

rollback tran

else

commit tran

Continued Next Page

24- 43 © Soaring Eagle Consulting 8/19/2013

Page 25: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Calling Stored Procedures from Transactions (Cont’d)

• What values are inserted in the tally table?

• How many transactions are active during the procedure?

• After the procedure returns?

/* proc has a tran also */

create procedure the_proc

as

begin tran proc_tran

insert tally values (2)

if @@error != 0

rollback tran

else

commit tran

return

Rolls back to outermost

tran in calling batch

Subsequent statements

in batch are processed

25- 43 © Soaring Eagle Consulting 8/19/2013

Page 26: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Stored Procedures and Transactions: Notes

• SQL Server notes the transaction nesting level before calling a stored procedure.

• If the transaction nesting level when the procedure returns is different from the level when executed, SQL Server will display the following message:

Transaction count after EXECUTE indicates that a

COMMIT or ROLLBACK TRANSACTION statement is missing

26- 43 © Soaring Eagle Consulting 8/19/2013

Page 27: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Stored Procedures and Transactions: Notes (Cont’d)

• This message indicates that transaction nesting is not synchronized

• Because a stored procedure does not abort the batch on a rollback tran, a rollback tran inside the proc could result in a loss of data integrity if subsequent statements are executed and committed

• A rollback tran rolls back all statements to the outermost transaction, including any work performed inside nested stored procedures that have not been fully committed (i.e., @@trancount > 0)

• A commit tran within the stored procedure only decrements @@trancount by one

27- 43 © Soaring Eagle Consulting 8/19/2013

Page 28: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Stored Procedures and Transactions: Guidelines

• Develop a consistent error handling strategy for failed transactions or other errors that occur within transactions

– Implement this strategy consistently across procedures/applications

• Implement transaction control in nested stored procedures

– Check whether the procedure is being called from within a transaction before issuing a begin tran

• Because rollback tran from a procedure does not abort the batch calling the procedure, follow these guidelines:

– Procedures should make no net change to @@trancount

– Issue a rollback tran only if the stored procedure issues the begin tran statement

28- 43 © Soaring Eagle Consulting 8/19/2013

Page 29: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

How To: Called or Stand-Alone Procedure Template

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

** but rolls back changes within the proc

** VERY IMPORTANT: return an error code

** to tell the calling procedure rollback occurred */

create proc p1

as

declare @trncnt int

select @trncnt = @@trancount -- save @@trancount value

if @trncnt = 0 -- transaction has not begun

begin tran p1 -- begin tran increments nest level to 1

else -- already in a transaction

save tran p1 -- save tran doesn’t increment nest level

Continued Next Page

29- 43 © Soaring Eagle Consulting 8/19/2013

Page 30: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

How To: Called or Stand-Alone Procedure Template

/* do some processing */

if (@@error <> 0) -- or other error condition

begin rollback tran p1 -- 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 p1 -- commit tran,

-- decrement @@trancount to 0

-- commit not required with

-- save tran

return 0 /* successful return */

Continued Next Page

30- 43 © Soaring Eagle Consulting 8/19/2013

Page 31: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Using Temporary Tables in Stored Procedures

• Temporary tables must be created before they can be referenced within a stored procedure

• A single stored procedure can create and reference a temp table as long as the creation statement is executed before any SQL statements which reference the table

• If a called-procedure references a temporary table or a regular table created externally, a temporary table with the same name and structure no longer has to exist at the time the stored procedure is created

31- 43 © Soaring Eagle Consulting 8/19/2013

Page 32: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Temporary Table Performance Tips

• Keep temporary tables as small as possible, vertically and horizontally

– Select only required columns, rather than “select *”

• Consider creating indexes on temp tables within your stored procedure

– If the temporary table is of sufficient size and is going to be accessed multiple times, it may be cost effective to create an index on it

• Always drop temporary tables as soon as possible

– Watch out for mysterious periodic slowdowns if you are creating very large temporary tables: the server may be checkpointing tempdb

32- 43 © Soaring Eagle Consulting 8/19/2013

Page 33: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Indexes on Temporary Tables

create proc p1 as

select title_id, type, pub_id, ytd_sales

into #temp_titles

from titles

where price between $8 and $10

create clustered index tmp on #temp_titles(pub_id)

select sum(ytd_sales)

from #temp_titles

where pub_id ='1324'

Continued Next Page

33- 43 © Soaring Eagle Consulting 8/19/2013

Page 34: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Indexes on Temporary Tables (Cont’d)

Question

Will the stored procedure use the index?

-YES!

select min(ytd_sales)

from #temp_titles

where pub_id = '4324'

return

34- 43 © Soaring Eagle Consulting 8/19/2013

Page 35: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Stored Procedure Debugging Techniques

Write it as a batch first

• To get the syntax right on a stored procedure, write small parts of it as a batch first, then store the procedure once the whole operation starts working

Get showplan output with recompile

• showplan output are generated by the optimizer, which is only operating when a procedure is recompiled. To see the effect of different parameters on optimization, create the procedure with recompile, then drop and recreate the procedure without it when you go into production

35- 43 © Soaring Eagle Consulting 8/19/2013

Page 36: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Temp Procedures

• SQL Server provides the capability of creating temporary stored procedures

• A stored procedure with a # in front of its name is a temporary procedure accessed only by the current connection

• A stored procedure with a ## in front of its name is a temporary procedure accessible by other connections

• They both go away when the connection is lost

• With SQL Server, you should not create a temporary stored procedure. Instead use the sp_executesql stored procedure or exec (@string)

36- 43 © Soaring Eagle Consulting 8/19/2013

Page 37: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Procedure Optimization

• Object references are resolved at execution time

• The query plan is generated at execution time

• Long procedures will still run faster than in-line SQL, because there will be fewer network packets sent to the server

37- 43 © Soaring Eagle Consulting 8/19/2013

Page 38: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Summary

• Use proper error handling and return status methods

• Watch out for rollback in a transaction

38- 43 © Soaring Eagle Consulting 8/19/2013

Page 39: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Lab: Stored Procedures

Part 1 Set statistics io and display actual plan, then run the following queries and compare the query plans and I/O

Write a stored procedure called procN where N is your user number as follows

select count(id) from pt_sample_CIidNCk where key2 between 0 and 500 select count(id) from pt_sample_CIidNCk where key2 between 35000 and 50000

create proc procN (@lo int = null, @hi int = null) as if @lo = null or @hi = null begin

39- 60 © Soaring Eagle Consulting 8/19/2013

Page 40: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Lab: Stored Procedures

Make sure showplan and statistics io are on and execute your stored procedure as follows, comparing query plans and total I/O for each execution

print ‘Syntax: procN 1,500’

return

end

select * from pt_sample_CIidNCk

where key2 between @lo and @hi

return

exec procN 0, 500

exec procN 35000, 50000

exec procN 35000, 50000 with recompile

exec procN 0, 500

40- 43 © Soaring Eagle Consulting 8/19/2013

Page 41: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Lab: Stored Procedures

Create a second version of procN as procN_2 with the “with recompile” option

Set statistics io, statistics time on, look at these and the graphical plan. Execute procN and procN_2 as follows

exec procN 35000, 50000

exec procN_2 35000, 50000

exec procN_2 0, 500

exec procN 0,500

exec procN 0,500 with recompile

41- 43 © Soaring Eagle Consulting 8/19/2013

Page 42: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Lab: Stored Procedures

Compare query plans, I/O, and compile, cpu, and elapsed times

Part 2

Create a proc that creates a temporary table with an index inside the procedure, then execute a select statement to make use of the index (don't force an index). Execute and look at query plan and statistics. Now rewrite the proc to force the index and review the statistics

42- 43 © Soaring Eagle Consulting 8/19/2013

Page 43: Everything you wanted to know about Stored Procedures! · Returning Procedure Status • Every stored procedure automatically returns an integer status value –Zero is returned on

Thank you!

Questions?

Jeff Garbus [email protected]

813-641-3434

43- 43 © Soaring Eagle Consulting 8/19/2013