语法
CREATE PROC [ EDURE ] procedure_name [ ; number ]
[ { @parameter data_type }
[ VARYING ] [ = default ] [ OUTPUT ]
] [ ,...n ]
[ WITH
{ RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ]
[ FOR REPLICATION ]
AS sql_statement [ ...n ]
参数
procedure_name
新存储过E的名称。过E名必须W合标识W规则,且对于数据库及其所有者必d一。有x多信息,请参见用标识符?br /> 要创建局部时过E,可以?procedure_name 前面加一个编L (#procedure_name)Q要创徏全局临时q程Q可以在 procedure_name 前面加两个编L (##procedure_name)。完整的名称Q包?# ?##Q不能超q?128 个字W。指定过E所有者的名称是可选的?br />
;number
是可选的整数Q用来对同名的过E分l,以便用一?DROP PROCEDURE 语句卛_同l的q程一起除厅R例如,名ؓ orders 的应用程序用的q程可以命名?orderproc;1、orderproc;2 {。DROP PROCEDURE orderproc 语句除L个组。如果名UC包含定界标识W,则数字不应包含在标识W中Q只应在 procedure_name 前后使用适当的定界符?/p>
@parameter
q程中的参数。在 CREATE PROCEDURE 语句中可以声明一个或多个参数。用户必d执行q程时提供每个所声明参数的|除非定义了该参数的默认|。存储过E最多可以有 2.100 个参数?/p>
使用 @ W号作ؓW一个字W来指定参数名称。参数名U必ȝ合标识符的规则。每个过E的参数仅用于该q程本nQ相同的参数名称可以用在其它q程中。默认情况下Q参数只能代替常量,而不能用于代替表名、列名或其它数据库对象的名称。有x多信息,请参?EXECUTE?
data_type
参数的数据类型。所有数据类型(包括 text、ntext ?imageQ均可以用作存储q程的参数。不q,cursor 数据cd只能用于 OUTPUT 参数。如果指定的数据cd?cursorQ也必须同时指定 VARYING ?OUTPUT 关键字。有?SQL Server 提供的数据类型及其语法的更多信息Q请参见数据cd?
说明 对于可以?cursor 数据cd的输出参敎ͼ没有最大数目的限制?/p>
VARYING
指定作ؓ输出参数支持的结果集Q由存储q程动态构造,内容可以变化Q。仅适用于游标参数?/p>
default
参数的默认倹{如果定义了默认|不必指定该参数的值即可执行过E。默认值必L帔R?NULL。如果过E将对该参数使用 LIKE 关键字,那么默认g可以包含通配W(%、_、[] ?[^]Q?/p>
OUTPUT
表明参数是返回参数。该选项的值可以返回给 EXEC[UTE]。?OUTPUT 参数可将信息q回l调用过E。Text、ntext ?image 参数可用?OUTPUT 参数。?OUTPUT 关键字的输出参数可以是游标占位符?/p>
n
表示最多可以指?2.100 个参数的占位W?/p>
{RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION}
RECOMPILE 表明 SQL Server 不会~存该过E的计划Q该q程在q行旉新编译。在使用非典型值或临时D不希望覆盖~存在内存中的执行计划时Q请使用 RECOMPILE 选项?/p>
ENCRYPTION 表示 SQL Server 加密 syscomments 表中包含 CREATE PROCEDURE 语句文本的条目。?ENCRYPTION 可防止将q程作ؓ SQL Server 复制的一部分发布?/p>
说明 在升U过E中QSQL Server 利用存储?syscomments 中的加密注释来重新创建加密过E?/p>
FOR REPLICATION
指定不能在订阅服务器上执行ؓ复制创徏的存储过E?使用 FOR REPLICATION 选项创徏的存储过E可用作存储q程{选,且只能在复制q程中执行。本选项不能?WITH RECOMPILE 选项一起用?/p>
AS
指定q程要执行的操作?/p>
sql_statement
q程中要包含的Q意数目和cd?Transact-SQL 语句。但有一些限制?/p>
n
是表C此q程可以包含多条 Transact-SQL 语句的占位符?/p>
注释
存储q程的最大大ؓ 128 MB?/p>
用户定义的存储过E只能在当前数据库中创徏Q时过E除外,临时q程L?tempdb 中创建)。在单个批处理中QCREATE PROCEDURE 语句不能与其?Transact-SQL 语句l合使用?
默认情况下,参数可ؓI。如果传?NULL 参数值ƈ且该参数?CREATE ?ALTER TABLE 语句中用,而该语句中引用的列又不允怋?NULLQ则 SQL Server 会生一条错误信息。ؓ了防止向不允怋?NULL 的列传?NULL 参数|应向q程中添加编E逻辑或ؓ该列使用默认|使用 CREATE ?ALTER TABLE ?DEFAULT 关键??/p>
在存储过E的M CREATE TABLE ?ALTER TABLE 语句中都为每列显式指?NULL ?NOT NULLQ例如在创徏临时表时。ANSI_DFLT_ON ?ANSI_DFLT_OFF 选项控制 SQL Server 为列指派 NULL ?NOT NULL Ҏ的方式Q如果在 CREATE TABLE ?ALTER TABLE 语句中没有指定的话)。如果某个连接执行的存储q程对这些选项的设|与创徏该过E的q接的设|不同,则ؓW二个连接创建的表列可能会有不同的ؓI性,q且表现Z同的行ؓ方式。如果ؓ每个列显式声明了 NULL ?NOT NULLQ那么将Ҏ有执行该存储q程的连接用相同的为空性创Z时表?/p>
在创建或更改存储q程ӞSQL Server 保?SET QUOTED_IDENTIFIER ?SET ANSI_NULLS 的设|。执行存储过E时Q将使用q些原始讄。因此,所有客L会话?SET QUOTED_IDENTIFIER ?SET ANSI_NULLS 讄在执行存储过E时都将被忽略。在存储q程中出现的 SET QUOTED_IDENTIFIER ?SET ANSI_NULLS 语句不媄响存储过E的功能?/p>
其它 SET 选项Q例?SET ARITHABORT、SET ANSI_WARNINGS ?SET ANSI_PADDINGSQ在创徏或更改存储过E时不保存。如果存储过E的逻辑取决于特定的讄Q应在过E开头添加一?SET 语句Q以保讄正确。从存储q程中执?SET 语句Ӟ该设|只在存储过E完成之前有效。之后,讄恢复ؓ调用存储q程时的倹{这使个别的客户端可以设|所需的选项Q而不会媄响存储过E的逻辑?/p>
说明 SQL Server 是将I字W串解释为单个空D是解释ؓ真正的空字符Ԍ由兼容别设|控制。如果兼容别小于或{于 65QSQL Server 将I字W串解释为单个空根{如果兼容别等?70Q则 SQL Server 空字符串解释ؓI字W串。有x多信息,请参?sp_dbcmptlevel?
获得有关存储q程的信?br />若要昄用来创徏q程的文本,请在q程所在的数据库中执行 sp_helptextQƈ使用q程名作为参数?
说明 使用 ENCRYPTION 选项创徏的存储过E不能?sp_helptext 查看?/p>
若要昄有关q程引用的对象的报表Q请使用 sp_depends?
若要E重命名Q请使用 sp_rename?
引用对象
SQL Server 允许创徏的存储过E引用尚不存在的对象。在创徏Ӟ只进行语法检查。执行时Q如果高速缓存中无有效的计划,则编译存储过E以生成执行计划。只有在~译q程中才解析存储q程中引用的所有对象。因此,如果语法正确的存储过E引用了不存在的对象Q则仍可以成功创建,但在q行时将p|Q因为所引用的对象不存在。有x多信息,请参见gq名U解析和~译?
延迟名称解析和兼容?br />SQL Server 允许 Transact-SQL 存储q程在创建时引用不存在的表。这U能力称为gq名U解析。不q,如果 Transact-SQL 存储q程引用了该存储q程中定义的表,而兼容别设|(通过执行 sp_dbcmptlevel 来设|)?65Q则在创建时会发告信息。而如果在q行时所引用的表不存在,返回错误信息。有x多信息,请参?sp_dbcmptlevel 和gq名U解析和~译?
执行存储q程
成功执行 CREATE PROCEDURE 语句后,q程名称存储在 sysobjects pȝ表中Q?CREATE PROCEDURE 语句的文本将存储?syscomments 中。第一ơ执行时Q将~译该过E以定索数据的最佌问计划?/p>
使用 cursor 数据cd的参?br />存储q程只能?cursor 数据cd用于 OUTPUT 参数。如果ؓ某个参数指定?cursor 数据cdQ也必须指定 VARYING ?OUTPUT 参数。如果ؓ某个参数指定?VARYING 关键字,则数据类型必L cursorQƈ且必L?OUTPUT 关键字?/p>
说明 cursor 数据cd不能通过数据?APIQ例?OLE DB、ODBC、ADO ?DB-LibraryQ绑定到应用E序变量上。因为必dl定 OUTPUT 参数Q应用程序才可以执行存储q程Q所以带?cursor OUTPUT 参数的存储过E不能通过数据?API 调用。只有将 cursor OUTPUT 变量赋值给 Transact-SQL 局?cursor 变量Ӟ才可以通过 Transact-SQL 批处理、存储过E或触发器调用这些过E?/p>
Cursor 输出参数
在执行过E时Q以下规则适用?cursor 输出参数Q?
对于只进游标Q游标的l果集中q回的行只是那些存储q程执行l束时处于或出游标位置的行Q例如:
在过E中的名?RS ?100 行结果集上打开一个非滚动游标?
q程提取l果?RS 的头 5 行?/p>
q程q回到其调用者?/p>
q回到调用者的l果?RS ?RS 的第 6 ?100 行组成,调用者中的游标处?RS 的第一行之前?
对于只进游标Q如果存储过E完成后Q游标位于第一行的前面Q则整个l果集将q回l调用批处理、存储过E或触发器。返回时Q游标将位于W一行的前面?/p>
对于只进游标Q如果存储过E完成后Q游标的位置出最后一行的l尾Q则用批处理、存储过E或触发器返回空l果集?
说明 I结果集与空g同?/p>
对于可滚动游标,在存储过E执行结束时Q结果集中的所有行均会q回l调用批处理、存储过E或触发器。返回时Q游标保留在q程中最后一ơ执行提取时的位|?/p>
对于Lcd的游标,如果游标关闭Q则空g递回调用批处理、存储过E或触发器。如果将游标指派l一个参敎ͼ但该游标从未打开q,也会出现q种情况?
说明 关闭状态只有在q回时才有媄响。例如,可以在过E中关闭游标Q稍后再打开游标Q然后将该游标的l果集返回给调用批处理、存储过E或触发器?/p>
临时存储q程
SQL Server 支持两种临时q程Q局部时过E和全局临时q程。局部时过E只能由创徏该过E的q接使用。全局临时q程则可由所有连接用。局部时过E在当前会话l束时自动除厅R全局临时q程在用该q程的最后一个会话结束时除去。通常是在创徏该过E的会话l束时?/p>
临时q程?# ?## 命名Q可以由M用户创徏。创E后Q局部过E的所有者是唯一可以使用该过E的用户。执行局部时过E的权限不能授予其他用户。如果创Z全局临时q程Q则所有用户均可以讉K该过E,权限不能昑ּ废除。只有在 tempdb 数据库中h昑ּ CREATE PROCEDURE 权限的用P才可以在该数据库中显式创Z时过E(不用编L命名Q。可以授予或废除q些q程中的权限?
说明 频繁使用临时存储q程会在 tempdb 中的pȝ表上产生争用Q从而对性能产生负面影响。徏议?sp_executesql 代替。sp_executesql 不在pȝ表中存储数据Q因此可以避免这一问题?/p>
自动执行存储q程
SQL Server 启动时可以自动执行一个或多个存储q程。这些存储过E必ȝpȝ理员创建,q在 sysadmin 固定服务器角色下作ؓ后台q程执行。这些过E不能有M输入参数?
对启动过E的数目没有限制Q但是要注意Q每个启动过E在执行旉会占用一个连接。如果必d启动时执行多个过E,但不需要ƈ行执行,则可以指定一个过E作为启动过E,让该q程调用其它q程。这样就只占用一个连接?/p>
在启动时恢复了最后一个数据库后,卛_始执行存储过E。若要蟩q这些存储过E的执行Q请启动参数指定ؓ跟踪标记 4022。如果以最低配|启?SQL ServerQ?-f 标记Q,则启动存储过E也不会执行。有x多信息,请参见跟t标记?
若要创徏启动存储q程Q必M?sysadmin 固定服务器角色的成员dQƈ?master 数据库中创徏存储q程?/p>
使用 sp_procoption 可以Q?
现有存储过E指定ؓ启动q程?/p>
停止?SQL Server 启动时执行过E?/p>
查看 SQL Server 启动时执行的所有过E的列表?
存储q程嵌套
存储q程可以嵌套Q即一个存储过E可以调用另一个存储过E。在被调用过E开始执行时Q嵌套增加,在被调用q程执行l束后,嵌套U将减少。如果超出最大的嵌套U,会整个调用q程铑֤败。可?@@NESTLEVEL 函数q回当前的嵌套?/p>
若要估计~译后的存储q程大小Q请使用下列性能监视计数器?
性能监视器对象名 性能监视计数器名U?
SQLServerQ缓冲区理?高速缓存大(面敎ͼ
SQLServerQ高速缓存管理器 高速缓存命中率
高速缓存页
高速缓存对象计?
* 各种分类的高速缓存对象均可以使用q些计数器,包括Ҏ sql、准?sql、过E、触发器{?/p>
有关更多信息Q请参见 SQL Server:Buffer Manager 对象?SQL Server:Cache Manager 对象?
sql_statement 限制
除了 SET SHOWPLAN_TEXT ?SET SHOWPLAN_ALL 之外Q这两个语句必须是批处理中仅有的语句Q,M SET 语句均可以在存储q程内部指定。所选择?SET 选项在存储过E执行过E中有效Q之后恢复ؓ原来的设|?
如果其他用户要用某个存储过E,那么在该存储q程内部Q一些语句用的对象名必M用对象所有者的名称限定。这些语句包括:
ALTER TABLE
CREATE INDEX
CREATE TABLE
所?DBCC 语句
DROP TABLE
DROP INDEX
TRUNCATE TABLE
UPDATE STATISTICS
权限
CREATE PROCEDURE 的权限默认授?sysadmin 固定服务器角色成员和 db_owner ?db_ddladmin 固定数据库角色成员。sysadmin 固定服务器角色成员和 db_owner 固定数据库角色成员可以将 CREATE PROCEDURE 权限转让l其他用戗执行存储过E的权限授予q程的所有者,该所有者可以ؓ其它数据库用戯|执行权限?/p>
CZ
A. 使用带有复杂 SELECT 语句的简单过E?br />下面的存储过E从四个表的联接中返回所有作者(提供了姓名)、出版的书籍以及出版C。该存储q程不用Q何参数?/p>
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
au_info_all 存储q程可以通过以下Ҏ执行Q?/p>
EXECUTE au_info_all
-- Or
EXEC au_info_all
如果该过E是批处理中的第一条语句,则可使用Q?/p>
au_info_all
B. 使用带有参数的简单过E?br />下面的存储过E从四个表的联接中只q回指定的作者(提供了姓名)、出版的书籍以及出版C。该存储q程接受与传递的参数_匚w的倹{?/p>
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
au_info 存储q程可以通过以下Ҏ执行Q?/p>
EXECUTE au_info 'Dull', 'Ann'
-- Or
EXECUTE au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
EXECUTE au_info @firstname = 'Ann', @lastname = 'Dull'
-- Or
EXEC au_info 'Dull', 'Ann'
-- Or
EXEC au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
EXEC au_info @firstname = 'Ann', @lastname = 'Dull'
如果该过E是批处理中的第一条语句,则可使用Q?/p>
au_info 'Dull', 'Ann'
-- Or
au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
au_info @firstname = 'Ann', @lastname = 'Dull'
C. 使用带有通配W参数的单过E?br />下面的存储过E从四个表的联接中只q回指定的作者(提供了姓名)、出版的书籍以及出版C。该存储q程对传递的参数q行模式匚wQ如果没有提供参敎ͼ则用预讄默认倹{?/p>
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
au_info2 存储q程可以用多U组合执行。下面只列出了部分组合:
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%'
D. 使用 OUTPUT 参数
OUTPUT 参数允许外部q程、批处理或多?Transact-SQL 语句讉K在过E执行期间设|的某个倹{下面的CZ创徏一个存储过E?(titles_sum)Qƈ使用一个可选的输入参数和一个输出参数?/p>
首先Q创E:
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
接下来,该 OUTPUT 参数用于控制语a?
说明 OUTPUT 变量必须在创和用该变量旉q行定义?/p>
参数名和变量名不一定要匚wQ不q数据类型和参数位置必须匚wQ除非?@@SUM = variable 形式Q?
DECLARE @@TOTALCOST money
EXECUTE titles_sum 'The%', @@TOTALCOST OUTPUT
IF @@TOTALCOST < 200
BEGIN
PRINT ' '
PRINT 'All of these titles can be purchased for less than $200.'
END
ELSE
SELECT 'The total cost of these titles is $'
+ RTRIM(CAST(@@TOTALCOST AS varchar(20)))
下面是结果集Q?/p>
Title Name
------------------------------------------------------------------------
The Busy Executive's Database Guide
The Gourmet Microwave
The Psychology of Computer Cooking
(3 row(s) affected)
Warning, null value eliminated from aggregate.
All of these titles can be purchased for less than $200.
E. 使用 OUTPUT 游标参数
OUTPUT 游标参数用来存储过E的局部游标传递回调用批处理、存储过E或触发器?/p>
首先Q创Z下过E,?titles 表上声明q打开一个游标:
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
接下来,执行一个批处理Q声明一个局部游标变量,执行上述q程以将游标赋值给局部变量,然后从该游标提取行?/p>
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
F. 使用 WITH RECOMPILE 选项
如果E提供的参数不是典型的参敎ͼq且新的执行计划不应高速缓存或存储在内存中QWITH RECOMPILE 子句会很有帮助?/p>
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. 使用 WITH ENCRYPTION 选项
WITH ENCRYPTION 子句对用户隐藏存储过E的文本。下例创建加密过E,使用 sp_helptext pȝ存储q程获取关于加密q程的信息,然后试直接?syscomments 表中获取关于该过E的信息?/p>
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'encrypt_this' AND type = 'P')
DROP PROCEDURE encrypt_this
GO
USE pubs
GO
CREATE PROCEDURE encrypt_this
WITH ENCRYPTION
AS
SELECT *
FROM authors
GO
EXEC sp_helptext encrypt_this
下面是结果集Q?/p>
The object's comments have been encrypted.
接下来,选择加密存储q程内容的标识号和文本?/p>
SELECT c.id, c.text
FROM syscomments c INNER JOIN sysobjects o
ON c.id = o.id
WHERE o.name = 'encrypt_this'
下面是结果集Q?/p>
说明 text 列的输出昄在单独一行中。执行时Q该信息与 id 列信息出现在同一行中?/p>
id text
---------- ------------------------------------------------------------
1413580074 ?????????????????????????????????e??????????????????????????????????????????????????????????????????????????
(1 row(s) affected)
H. 创徏用户定义的系l存储过E?br />下面的示例创Z个过E,昄表名?emp 开头的所有表及其对应的烦引。如果没有指定参敎ͼ该过E将q回表名?sys 开头的所有表Q及索引Q?/p>
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'sp_showindexes' AND type = 'P')
DROP PROCEDURE sp_showindexes
GO
USE master
GO
CREATE PROCEDURE sp_showindexes
@@TABLE varchar(30) = 'sys%'
AS
SELECT o.name AS TABLE_NAME,
i.name AS INDEX_NAME,
indid AS INDEX_ID
FROM sysindexes i INNER JOIN sysobjects o
ON o.id = i.id
WHERE o.name LIKE @@TABLE
GO
USE pubs
EXEC sp_showindexes 'emp%'
GO
下面是结果集Q?/p>
TABLE_NAME INDEX_NAME INDEX_ID
---------------- ---------------- ----------------
employee employee_ind 1
employee PK_emp_id 2
(2 row(s) affected)
I. 使用延迟名称解析
下面的示例显C四个过E以及gq名U解析的各种可能使用方式。尽引用的表或列在~译时不存在Q但每个存储q程都可创徏?/p>
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'proc1' AND type = 'P')
DROP PROCEDURE proc1
GO
-- Creating a procedure on a nonexistent table.
USE pubs
GO
CREATE PROCEDURE proc1
AS
SELECT *
FROM does_not_exist
GO
-- Here is the statement to actually see the text of the procedure.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c
ON o.id = c.id
WHERE o.type = 'P' AND o.name = 'proc1'
GO
USE master
GO
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'proc2' AND type = 'P')
DROP PROCEDURE proc2
GO
-- Creating a procedure that attempts to retrieve information from a
-- nonexistent column in an existing table.
USE pubs
GO
CREATE PROCEDURE proc2
AS
DECLARE @middle_init char(1)
SET @middle_init = NULL
SELECT au_id, middle_initial = @middle_init
FROM authors
GO
-- Here is the statement to actually see the text of the procedure.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c
ON o.id = c.id
WHERE o.type = 'P' and o.name = 'proc2'