1. Advantages of Stored Procedures
Using stored procedures provides many advantages over
executing large and complex SQL batches from client applications.
Following are some of them:
Modular programming—
Subroutines and functions are often used in ordinary 3GL and 4GL
languages (such as C, C++, and Microsoft Visual Basic) to break code
into smaller, more manageable pieces. The same advantages are achieved
when using stored procedures, with the difference that the stored
procedure is stored in SQL Server and can be called by any client
application. Restricted, function-based access to tables—
A user can have permission to execute a stored procedure without having
permissions to operate directly on the underlying tables. Reduced network traffic—
Stored procedures can consist of many individual SQL statements but can
be executed with a single statement. This allows you to reduce the
number and size of calls from the client to the server. Faster execution—
Stored procedures’ query plans are kept in memory after the first
execution. The code doesn’t have to be reparsed and reoptimized on
subsequent executions. Enforced consistency—
If users modify data only through stored procedures, problems that
often result from ad hoc modifications (such as omitting a crucial WHERE clause) are eliminated. Reduced operator and programmer errors— Because less information is being passed, complex tasks can be executed more easily, with less likelihood of SQL errors. Automating complex or sensitive transactions— If all modifications of certain tables take place in stored procedures, you can guarantee the data integrity on those tables.
Some of the disadvantages of using stored procedures (depending on the environment) are as follows:
Increase in server processing requirements—
Using stored procedures can increase the amount of processing that
takes place on the server. In a large user environment with considerable
activity in the server, it may be more desirable to offload some of the
processing to the client workstation. Less cross-DBMS portability—
Although the ANSI-99 SQL standard provides a standard for stored
procedures in database management systems (DBMSs), the format and
structure are different from those of SQL Server stored procedures.
These procedures would all have to be rewritten to be compatible with another DBMS environment.
Should you use stored procedures? The answer is (as it often is), it depends.
If you are working in a two-tier environment, using
stored procedures is often advantageous. The trend is shifting to three-
(or more) tier environments. In such environments, business logic is
often handled in some middle tier (possibly ActiveX objects managed by
Microsoft Transaction Server). If you operate in that type of
environment, you might want to restrict the stored procedures to
performing basic data-related tasks, such as retrievals, insertions,
updates, and deletions.
Note
You can use stored procedures to make a database sort
of a “black box” as far as the developers and the application code are
concerned. If all database access is managed through stored procedures,
the applications are shielded from possible changes to the underlying
database structures.
For example, one organization
found the need to split one table across multiple databases. By simply
modifying the existing stored procedures to handle the multiple tables
and by using distributed partitioned views, the company was able to make
this change without requiring any changes to the front-end application
code. 2. Creating Stored Procedures
To create a stored procedure, you need to give the
procedure a unique name within the schema and then write the sequence of
SQL statements to be executed within the procedure. Following is the
basic syntax for creating stored procedures:
CREATE { PROC | PROCEDURE } [schema_name.]procedure_name [ ; number ]
[ { @parameter [ schema_name.]data_type }
[ VARYING ] [ = default ] [ OUT | OUTPUT ] [READONLY]
] [ ,...n ]
[ WITH { [ ENCRYPTION ]
, [ RECOMPILE ]
, [ EXECUTE_AS_Clause ]
[ ,...n] ]
[ FOR REPLICATION ]
AS
[BEGIN]
SQL_Statements
[ RETURN scalar_expression ]
[END]
It is good programming practice to always end a procedure with the RETURN statement and to specify a return status other than 0 when an error condition occurs. Listing 1 shows a simple stored procedure that returns book titles and the names of the authors who wrote them.
Listing 1. A Sample Stored Procedure
use bigpubs2008
go
IF EXISTS ( SELECT * FROM sys.procedures
WHERE schema_id = schema_id('dbo')
AND name = N'title_authors')
DROP PROCEDURE dbo.title_authors
GO
CREATE PROCEDURE title_authors
AS
BEGIN
SELECT a.au_lname, a.au_fname, t.title
FROM titles t INNER JOIN
titleauthor ta ON t.title_id = ta.title_id RIGHT OUTER JOIN
authors a ON ta.au_id = a.au_id
RETURN 0
END
|
Creating Procedures in SSMS
To create a stored procedure in SSMS, open the object tree for the database in which you want to create the procedure, open the Programmability folder, right-click the Stored Procedures
folder, and from the context menu, choose New Stored Procedure. SSMS
opens a new query window, populated with code that is based on a default
template for stored procedures. Listing 2 shows an example of the default template code for a stored procedure that would be opened into a new query window.
Listing 2. An Example of a New Stored Procedure Creation Script Generated by SSMS
-- ================================================
-- Template generated from Template Explorer using:
-- Create Procedure (New Menu).SQL
--
-- Use the Specify Values for Template Parameters
-- command (Ctrl-Shift-M) to fill in the parameter
-- values below.
--
-- This block of comments will not be included in
-- the definition of the procedure.
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE PROCEDURE <Procedure_Name, sysname, ProcedureName>
- Add the parameters for the stored procedure here
<@Param1, sysname, @p1> <Datatype_For_Param1, , int> =
<Default_Value_For_Param1, , 0>,
<@Param2, sysname, @p2> <Datatype_For_Param2, , int> =
<Default_Value_For_Param2, , 0>
AS
BEGIN
- SET NOCOUNT ON added to prevent extra result sets from
- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT <@Param1, sysname, @p1>, <@Param2, sysname, @p2>
END
GO
|
You can modify the template code as necessary to set
the procedure name and to specify the parameters, return value, and
procedure body. When you are finished, you can execute the contents of
the query window to create the procedure. After you have created the
procedure successfully, it is recommended that you save the source code
to a file by choosing the Save or Save As option from the File menu.
This way, you can re-create the stored procedure from the file if it is
accidentally dropped from the database.
Tip
When you create a new stored procedure in SSMS, the procedure does not show up in the Stored Procedures folder in the Object Browser unless you right-click the Stored Procedures folder and choose the Refresh option.
One
thing you might notice about the stored procedure template is that it
contains template parameters for parameter names, procedure name, author
name, create date, and so on. These template parameters are in the
format <parameter, type, value>:
parameter_name is the name of the template parameter in the script. data_type is the optional data type of the template parameter. value is the default value to be used to replace every occurrence of the template parameter in the script
You can auto substitute values for template
parameters by selecting Query, Specify Values for Template Parameters or
by pressing Ctrl+Shift+M. This brings up the dialog shown in Figure 1.
You enter the values for the template parameters in
the Value column and then click OK. SSMS then substitutes any values you
specified wherever the template parameter is used within the template.
An alternative way to create a stored procedure from a
template is to use the Template Explorer in SSMS. You can open the
Template Explorer by selecting View, Template Explorer in SSMS or by
pressing Ctrl+Alt+T. The Template Explorer window appears in SSMS, as
shown in Figure 2.
You can double-click the name of the stored procedure
template you want to use or right-click the desired template and then
select Open. SSMS opens a new query window, populated with the template
code.
Note
It
is also possible to edit the provided stored procedure templates
available in the Template Explorer by right-clicking them and selecting
the Edit option. You can then customize the templates to include code
fragments, comments, or structure that is more to your preference and
save the changes to the template file. However, it is generally
recommended that you not modify the provided templates and instead
create your own custom templates.
Creating Custom Stored Procedure Templates
To create a custom stored procedure template, right-click the Stored Procedure
folder in the Template Explorer and select New. SSMS then creates an
entry in the Template Explorer, and you can specify the name for the
template.
To begin adding code to the template, right-click the
template and select Edit. This opens a query window in which you can
start entering the new template code. Probably the best way to get
started is to copy the template code from one of the templates provided
with SQL Server 2008 and then modify it as you desire. You then select
File, Save to save the template code to the file.
Listing 3 shows an example of a new stored procedure template.
Listing 3. An Example of Custom Stored Procedure Template
-- =============================================
-- Create basic stored procedure template
-- =============================================
-- Drop stored procedure if it already exists
IF EXISTS (
SELECT *
FROM sys.procedures
WHERE schema_id = schema_id('dbo')
AND name = N'<Proc_Name, sysname, myproc>'
)
DROP PROCEDURE <Schema_Name, sysname, dbo>.<Proc_Name, sysname, myproc>
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE PROCEDURE <Schema_Name, sysname, dbo>.<Proc_Name, sysname, myproc>
— Add the parameters for the stored procedure here
<@param1, sysname, @p1> <param1_type, , int> = <param1_default, , 0>,
<@param2, sysname, @p2> <param2_type, , int> = <param2_default, , 0>,
<@param3, sysname, @p3> <param3_type, , int> OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @trancnt int
SELECT @trancnt = @@TRANCOUNT
if @trancnt = 0
BEGIN TRAN <Proc_Name, sysname, myproc>
else
SAVE TRAN <Proc_Name, sysname, myproc>
/* Insert processing code here */
if (@@error != 0) -- check for error condition
begin
-- rollback to savepoint, or begin tran
rollback tran <Proc_Name, sysname, myproc>
-- return error code indicating rollback
return -101
end
/* Insert more processing here if required */
-- set value of output parameter
set <@param3,sysname, @p3> = <@param1,sysname, @p1> + <@param2,sysname, @p2>
if @trancnt = 0 -- this proc issued begin tran
-- commit tran, decrement @@trancount to 0
commit tran <Proc_Name, sysname, myproc>
-- commit not required with save tran
return 0 /* successful return */
END
GO
— =============================================
— Example to execute the stored procedure
— =============================================
DECLARE <@output_variable, sysname, @p3_output> <output_datatype, , int>
EXECUTE <Schema_name, sysname, dbo>.<Proc_name, sysname, myproc>
<@param1, sysname, @p1> = <param1_value, , 1>,
<@param2, sysname, @p2> = <param2_value, , 1>,
<@param3, sysname, @p3> = <@output_variable, sysname, @p3_output> OUTPUT
SELECT <@output_variable, sysname, @p3_output>
GO
|
After you define a custom
stored procedure template, you can use it as you would use the built-in
templates. You can double-click it or right-click and select Open, and
SSMS opens a new query window with a new stored procedure creation
script based on the custom template. If you use the default values for
the template parameters, after the parameter substitution, the CREATE PROCEDURE script looks like the one in Listing 4.
Listing 4. An Example of a CREATE PROCEDURE Script Generated from the Custom Stored Procedure Template
-- =============================================
-- Create basic stored procedure template
-- =============================================
-- Drop stored procedure if it already exists
IF EXISTS (
SELECT *
FROM sys.procedures
WHERE schema_id = schema_id('dbo')
AND name = N'myproc'
)
DROP PROCEDURE dbo.myproc
GO
-- =============================================
-- Author: Name
-- Create date:
-- Description:
-- =============================================
CREATE PROCEDURE dbo.myproc
— Add the parameters for the stored procedure here
@p1 int = 0,
@p2 int = 0,
@p3 int OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @trancnt int
SELECT @trancnt = @@TRANCOUNT
if @trancnt = 0
BEGIN TRAN myproc
else
SAVE TRAN myproc
/* Insert processing code here */
if (@@error != 0) -- check for error condition
begin
-- rollback to savepoint, or begin tran
rollback tran myproc
-- return error code indicating rollback
return -101
end
/* Insert more processing here if required */
-- set value of output parameter
set @p3 = @p1 + @p2
if @trancnt = 0 -- this proc issued begin tran
-- commit tran, decrement @@trancount to 0
commit tran myproc
-- commit not required with save tran
return 0 /* successful return */
END
GO
-- =============================================
-- Example to execute the stored procedure
-- =============================================
DECLARE @p3_output int
EXECUTE dbo.myproc
@p1 = 1,
@p2 = 1,
@p3 = @p3_output OUTPUT
SELECT @p3_output
GO
|
Temporary Stored Procedures
SQL
Server enables you to create private and global temporary stored
procedures. Temporary stored procedures are analogous to temporary
tables in that they can be created with the # and ## prefixes added to the procedure name. The # prefix denotes a local temporary stored procedure; ##
denotes a global temporary stored procedure. A local temporary stored
procedure can be executed only by the connection that created it, and
the procedure is automatically deleted when the connection is closed. A
global temporary stored procedure can be accessed by multiple
connections and exists until the connection used by the user who created
the procedure is closed and any currently executing versions of the
procedure by any other connections are completed.
If a stored procedure not prefixed with # or ## is created directly in the tempdb database, the stored procedure exists until SQL Server is shut down. Procedures created directly in tempdb continue to exist even after the creating connection is terminated.
Temporary
stored procedures are provided for backward compatibility with earlier
versions of SQL Server that did not support the reuse of execution plans
for T-SQL statements or batches. Applications connecting to SQL Server
2000 and higher should use the sp_executesql system stored procedure to execute dynamic SQL statements instead of creating temporary stored procedures.
Tip
It is strongly recommended that sp_executesql
be used instead of temporary stored procedures. Excessive use of
temporary stored procedures can lead to locking contention on the system
tables in tempdb, which can adversely affect overall system performance.
|