Professional Documents
Culture Documents
Procedures can be created for permanent use or for temporary use within a session
(local temporary procedure) or for temporary use within all sessions (global
temporary procedure).
Stored procedures can also be created to run automatically when Microsoft� SQL
Server� starts.
Syntax
CREATE PROC [ EDURE ] procedure_name [ ; number ]
[ { @parameter data_type }
[ VARYING ] [ = default ] [ OUTPUT ]
] [ ,...n ]
[ WITH
{ RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ]
[ FOR REPLICATION ]
AS sql_statement [ ...n ]
Arguments
procedure_name
Is the name of the new stored procedure. Procedure names must conform to the rules
for identifiers and must be unique within the database and its owner. For more
information, see Using Identifiers.
;number
Is an optional integer used to group procedures of the same name so they can be
dropped together with a single DROP PROCEDURE statement. For example, the
procedures used with an application called orders may be named orderproc;1,
orderproc;2, and so on. The statement DROP PROCEDURE orderproc drops the entire
group. If the name contains delimited identifiers, the number should not be
included as part of the identifier; use the appropriate delimiter around
procedure_name only.
@parameter
Specify a parameter name using an at sign (@) as the first character. The parameter
name must conform to the rules for identifiers. Parameters are local to the
procedure; the same parameter names can be used in other procedures. By default,
parameters can take the place only of constants; they cannot be used in place of
table names, column names, or the names of other database objects. For more
information, see EXECUTE.
data_type
Is the parameter data type. All data types, including text, ntext and image, can be
used as a parameter for a stored procedure. However, the cursor data type can be
used only on OUTPUT parameters. When you specify a data type of cursor, the VARYING
and OUTPUT keywords must also be specified. For more information about SQL Server -
supplied data types and their syntax, see Data Types.
Note There is no limit on the maximum number of output parameters that can be of
cursor data type.
VARYING
default
Is a default value for the parameter. If a default is defined, the procedure can be
executed without specifying a value for that parameter. The default must be a
constant or it can be NULL. It can include wildcard characters (%, _, [], and [^])
if the procedure uses the parameter with the LIKE keyword.
OUTPUT
Indicates that the parameter is a return parameter. The value of this option can be
returned to EXEC[UTE]. Use OUTPUT parameters to return information to the calling
procedure. Text, ntext, and image parameters can be used as OUTPUT parameters. An
output parameter using the OUTPUT keyword can be a cursor placeholder.
RECOMPILE indicates that SQL Server does not cache a plan for this procedure and
the procedure is recompiled at run time. Use the RECOMPILE option when using
atypical or temporary values without overriding the execution plan cached in
memory.
ENCRYPTION indicates that SQL Server encrypts the syscomments table entry
containing the text of the CREATE PROCEDURE statement. Using ENCRYPTION prevents
the procedure from being published as part of SQL Server replication.
Note During an upgrade, SQL Server uses the encrypted comments stored in
syscomments to re-create encrypted procedures.
FOR REPLICATION
Specifies that stored procedures created for replication cannot be executed on the
Subscriber. A stored procedure created with the FOR REPLICATION option is used as a
stored procedure filter and only executed during replication. This option cannot be
used with the WITH RECOMPILE option.
AS
sql_statement
Remarks
The maximum size of a stored procedure is 128 MB.
A user-defined stored procedure can be created only in the current database (except
for temporary procedures, which are always created in tempdb). The CREATE PROCEDURE
statement cannot be combined with other Transact-SQL statements in a single batch.
Parameters are nullable by default. If a NULL parameter value is passed and that
parameter is used in a CREATE or ALTER TABLE statement in which the column
referenced does not allow NULLs, SQL Server generates an error. To prevent passing
a NULL parameter value to a column that does not allow NULLs, add programming logic
to the procedure or use a default value (with the DEFAULT keyword of CREATE or
ALTER TABLE) for the column.
It is recommended that you explicitly specify NULL or NOT NULL for each column in
any CREATE TABLE or ALTER TABLE statement in a stored procedure, such as when
creating a temporary table. The ANSI_DFLT_ON and ANSI_DFLT_OFF options control the
way SQL Server assigns the NULL or NOT NULL attributes to columns if not specified
in a CREATE TABLE or ALTER TABLE statement. If a connection executes a stored
procedure with different settings for these options than the connection that
created the procedure, the columns of the table created for the second connection
can have different nullability and exhibit different behaviors. If NULL or NOT NULL
is explicitly stated for each column, the temporary tables are created with the
same nullability for all connections that execute the stored procedure.
SQL Server saves the settings of both SET QUOTED_IDENTIFIER and SET ANSI_NULLS when
a stored procedure is created or altered. These original settings are used when the
stored procedure is executed. Therefore, any client session settings for SET
QUOTED_IDENTIFIER and SET ANSI_NULLS are ignored during stored procedure execution.
SET QUOTED_IDENTIFIER and SET ANSI_NULLS statements that occur within the stored
procedure do not affect the functionality of the stored procedure.
Other SET options, such as SET ARITHABORT, SET ANSI_WARNINGS, or SET ANSI_PADDINGS
are not saved when a stored procedure is created or altered. If the logic of the
stored procedure is dependent on a particular setting, include a SET statement at
the start of the procedure to ensure the proper setting. When a SET statement is
executed from a stored procedure, the setting remains in effect only until the
stored procedure completes. The setting is then restored to the value it had when
the stored procedure was called. This allows individual clients to set the options
wanted without affecting the logic of the stored procedure.
Note Whether SQL Server interprets an empty string as either a single space or as
a true empty string is controlled by the compatibility level setting. If the
compatibility level is less than or equal to 65, SQL Server interprets empty
strings as single spaces. If the compatibility level is equal to 70, SQL Server
interprets empty strings as empty strings. For more information, see
sp_dbcmptlevel.
Note Stored procedures created with the ENCRYPTION option cannot be viewed with
sp_helptext.
Referencing Objects
SQL Server allows the creation of stored procedures that reference objects that do
not yet exist. At creation time, only syntax checking is done. The stored procedure
is compiled to generate an execution plan when executed, if a valid plan does not
already exist in the cache. Only during compilation are all objects referenced in
the stored procedure resolved. Thus, a syntactically correct stored procedure that
references objects which do not exist can be created successfully, but will fail at
run time because referenced objects do not exist. For more information, see
Deferred Name Resolution and Compilation.
Note The cursor data type cannot be bound to application variables through the
database APIs such as OLE DB, ODBC, ADO, and DB-Library. Because OUTPUT parameters
must be bound before an application can execute a stored procedure, stored
procedures with cursor OUTPUT parameters cannot be called from the database APIs.
These procedures can be called from Transact-SQL batches, stored procedures, or
triggers only when the cursor OUTPUT variable is assigned to a Transact-SQL local
cursor variable.
For a forward-only cursor, the rows returned in the cursor's result set are only
those rows at and beyond the position of the cursor at the conclusion of the stored
procedure executed, for example:
A nonscrollable cursor is opened in a procedure on a result set named RS of 100
rows.
The result set RS returned to the caller consists of rows from 6 through 100 of RS,
and the cursor in the caller is positioned before the first row of RS.
For a forward-only cursor, if the cursor is positioned before the first row upon
completion of the stored procedure, the entire result set is returned to the
calling batch, stored procedure, or trigger. When returned, the cursor position is
set before the first row.
For a forward-only cursor, if the cursor is positioned beyond the end of the last
row upon completion of the stored procedure, an empty result set is returned to the
calling batch, stored procedure, or trigger.
For a scrollable cursor, all the rows in the result set are returned to the calling
batch, stored procedure, or trigger at the conclusion of the execution of the
stored procedure. When returned, the cursor position is left at the position of the
last fetch executed in the procedure.
For any type of cursor, if the cursor is closed, then a null value is passed back
to the calling batch, stored procedure, or trigger. This will also be the case if a
cursor is assigned to a parameter, but that cursor is never opened.
Note The closed state matters only at return time. For example, it is valid to
close a cursor part way through the procedure, to open it again later in the
procedure, and return that cursor's result set to the calling batch, stored
procedure, or trigger.
Temporary procedures named with # and ## can be created by any user. When the
procedure is created, the owner of the local procedure is the only one who can use
it. Permission to execute a local temporary procedure cannot be granted for other
users. If a global temporary procedure is created, all users can access it;
permissions cannot be revoked explicitly. Explicitly creating a temporary procedure
in tempdb (naming without a number sign) can be performed only by those with
explicit CREATE PROCEDURE permission in the tempdb database. Permission can be
granted and revoked from these procedures.
Note Heavy use of temporary stored procedures can create contention on the system
tables in tempdb and adversely affect performance. It is recommended that
sp_executesql be used instead. sp_executesql does not store data in the system
tables and therefore avoids the problem.
There is no limit to the number of startup procedures you can have, but be aware
that each consumes one connection while executing. If you must execute multiple
procedures at startup but do not need to execute them in parallel, make one
procedure the startup procedure and have that procedure call the other procedures.
This uses only one connection.
Execution of the stored procedures starts when the last database is recovered at
startup. To skip launching these stored procedures, specify trace flag 4022 as a
startup parameter. If you start SQL Server with minimal configuration (using the -f
flag), the startup stored procedures are not executed. For more information, see
Trace Flags.
* These counters are available for various categories of cache objects including
adhoc sql, prepared sql, procedures, triggers, and so on.
For more information, see SQL Server: Buffer Manager Object and SQL Server: Cache
Manager Object.
sql_statement Limitations
Any SET statement can be specified inside a stored procedure except SET
SHOWPLAN_TEXT and SET SHOWPLAN_ALL, which must be the only statements in the batch.
The SET option chosen remains in effect during the execution of the stored
procedure and then reverts to its former setting.
Inside a stored procedure, object names used with certain statements must be
qualified with the name of the object owner if other users are to use the stored
procedure. The statements are:
ALTER TABLE
CREATE INDEX
CREATE TABLE
DROP TABLE
DROP INDEX
TRUNCATE TABLE
UPDATE STATISTICS
Permissions
CREATE PROCEDURE permissions default to members of the sysadmin fixed server role,
and the db_owner and db_ddladmin fixed database roles. Members of the sysadmin
fixed server role and the db_owner fixed database role can transfer CREATE
PROCEDURE permissions to other users. Permission to execute a stored procedure is
given to the procedure owner, who can then set execution permission for other
database users.
Examples
A. Use a simple procedure with a complex SELECT
This stored procedure returns all authors (first and last names supplied), their
titles, and their publishers from a four-table join. This stored procedure does not
use any parameters.
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'au_info_all' AND type = 'P')
DROP PROCEDURE au_info_all
GO
CREATE PROCEDURE au_info_all
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors a INNER JOIN titleauthor ta
ON a.au_id = ta.au_id INNER JOIN titles t
ON t.title_id = ta.title_id INNER JOIN publishers p
ON t.pub_id = p.pub_id
GO
EXECUTE au_info_all
-- Or
EXEC au_info_all
au_info_all
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'au_info' AND type = 'P')
DROP PROCEDURE au_info
GO
USE pubs
GO
CREATE PROCEDURE au_info
@lastname varchar(40),
@firstname varchar(20)
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors a INNER JOIN titleauthor ta
ON a.au_id = ta.au_id INNER JOIN titles t
ON t.title_id = ta.title_id INNER JOIN publishers p
ON t.pub_id = p.pub_id
WHERE au_fname = @firstname
AND au_lname = @lastname
GO
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'au_info2' AND type = 'P')
DROP PROCEDURE au_info2
GO
USE pubs
GO
CREATE PROCEDURE au_info2
@lastname varchar(30) = 'D%',
@firstname varchar(18) = '%'
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors a INNER JOIN titleauthor ta
ON a.au_id = ta.au_id INNER JOIN titles t
ON t.title_id = ta.title_id INNER JOIN publishers p
ON t.pub_id = p.pub_id
WHERE au_fname LIKE @firstname
AND au_lname LIKE @lastname
GO
The au_info2 stored procedure can be executed in many combinations. Only a few
combinations are shown here:
EXECUTE au_info2
-- Or
EXECUTE au_info2 'Wh%'
-- Or
EXECUTE au_info2 @firstname = 'A%'
-- Or
EXECUTE au_info2 '[CK]ars[OE]n'
-- Or
EXECUTE au_info2 'Hunter', 'Sheryl'
-- Or
EXECUTE au_info2 'H%', 'S%'
USE pubs
GO
IF EXISTS(SELECT name FROM sysobjects
WHERE name = 'titles_sum' AND type = 'P')
DROP PROCEDURE titles_sum
GO
USE pubs
GO
CREATE PROCEDURE titles_sum @@TITLE varchar(40) = '%', @@SUM money OUTPUT
AS
SELECT 'Title Name' = title
FROM titles
WHERE title LIKE @@TITLE
SELECT @@SUM = SUM(price)
FROM titles
WHERE title LIKE @@TITLE
GO
Note The OUTPUT variable must be defined during the table creation as well as
during use of the variable.
The parameter name and variable name do not have to match; however, the data type
and parameter positioning must match (unless @@SUM = variable is used).
Title Name
------------------------------------------------------------------------
The Busy Executive's Database Guide
The Gourmet Microwave
The Psychology of Computer Cooking
(3 row(s) affected)
First, create the procedure that declares and then opens a cursor on the titles
table:
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'titles_cursor' and type = 'P')
DROP PROCEDURE titles_cursor
GO
CREATE PROCEDURE titles_cursor @titles_cursor CURSOR VARYING OUTPUT
AS
SET @titles_cursor = CURSOR
FORWARD_ONLY STATIC FOR
SELECT *
FROM titles
OPEN @titles_cursor
GO
Next, execute a batch that declares a local cursor variable, executes the procedure
to assign the cursor to the local variable, and then fetches the rows from the
cursor.
USE pubs
GO
DECLARE @MyCursor CURSOR
EXEC titles_cursor @titles_cursor = @MyCursor OUTPUT
WHILE (@@FETCH_STATUS = 0)
BEGIN
FETCH NEXT FROM @MyCursor
END
CLOSE @MyCursor
DEALLOCATE @MyCursor
GO
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'titles_by_author' AND type = 'P')
DROP PROCEDURE titles_by_author
GO
CREATE PROCEDURE titles_by_author @@LNAME_PATTERN varchar(30) = '%'
WITH RECOMPILE
AS
SELECT RTRIM(au_fname) + ' ' + RTRIM(au_lname) AS 'Authors full name',
title AS Title
FROM authors a INNER JOIN titleauthor ta
ON a.au_id = ta.au_id INNER JOIN titles t
ON ta.title_id = t.title_id
WHERE au_lname LIKE @@LNAME_PATTERN
GO
G. Use the WITH ENCRYPTION option
The WITH ENCRYPTION clause hides the text of a stored procedure from users. This
example creates an encrypted procedure, uses the sp_helptext system stored
procedure to get information on that encrypted procedure, and then attempts to get
information on that procedure directly from the syscomments table.
Next, select the identification number and text of the encrypted stored procedure
contents.
Note The text column output is shown on a separate line. When executed, this
information appears on the same line as the id column information.
id text
---------- ------------------------------------------------------------
1413580074 ?????????????????????????????????
e??????????????????????????????????????????????????????????????????????????
(1 row(s) affected)
(2 row(s) affected)
See Also
ALTER PROCEDURE
Batches
Control-of-Flow Language
Cursors
DBCC
DECLARE @local_variable
DROP PROCEDURE
Functions
GRANT
SELECT
sp_addextendedproc
sp_depends
sp_helptext
sp_procoption
sp_recompile
sp_rename
System Tables
Using Comments