CREATE PROCEDURE GetUnitPrice @prod_id int, @unit_price money OUT-
PUT
AS
SELECT @unit_price = UnitPrice
FROM Products
WHERE ProductID = @prod_id
GO
您必须在呼叫程序中宣告变量,才可在预存过程调用中使用该变量。举例来说,在下面的程序代码中我们先宣告@price变量并将其数据型别设为money(它必须符合OUTPUT参数数据型别),然后执行此预存程序:
DECLARE @price money
EXECUTE GetUnitPrice 77, @unit_price = @price OUTPUT
PRINT CONVERT(varchar(6), @price)
GO
PRINT 陈述式为@price传回值13.00。请注意我们用 CONVERT 陈述式将@price由原来的money数据型别,转换为varchar数据型别,才可以将该值当成字符串、字符数据型别,或以不直接的方式转换成字符来打印(这些是 PRINT 陈述式的打印要求)。请注意在预存程序和呼叫程序中为 OUTPUT 使用不同名称的变量,以使您能够更方便的找到范例中变量的位置,并强调名称可以不同。
您也可以在执行预存程序时,使用变量指定输入值,让预存程序可以接收来自呼叫程序的数值,然后修改该值或利用该值以执行某种作业,再将新的值传回呼叫程序。操作方法为在执行预存程序前,先为呼叫程序中的某变量分配一个值(或执行查询以在变量中插入值),再将该变量传送到预存程序中。现在就来看看如何在预存程序中使用区域变量。
在预存程序中使用区域变量
DECLARE 关键词用于建立区域变量,在建立区域变量时,就要指定区域变量名称及数据型别,而名称必须以 @ 前缀为前置字。一但变量宣告,其值会先被设为 NULL。
区域变量可在批次操作、指令码(或呼叫程序)或预存程序中宣告。预存程序中的变量通常用来储存条件陈述式所测试传回的数据值,或是储存预存程序 RETURN 陈述式所传回的数据值。变数也常被用来当作计数器。变量范围从变量的宣告处开始,宣告该变量的预存程序结束后,该变量就不再有效。
现在就来看一个包含区域变量的预存程序。该预存程序使用 WHILE 循环结构插入五个数据列到数据表中。首先建立一个范例数据表,命名为mytable,然后建立一个预存程序,命名为InsertRows。在程序中将使用@loop_counter和@start_val这两个区域变量,我们会一起宣告这两个变量,并且以逗号将两变量区隔。以下为使用 T-SQL 程序代码建立数据表和预存程序的方法:
USE MyDB
GO
CREATE TABLE mytable
(
column1 int,
column2 char(10)
)
GO
CREATE PROCEDURE InsertRows @start_value int
AS
DECLARE @loop_counter int, @start_val int
SET @start_val = @start_value - 1
SET @loop_counter = 0
WHILE (@loop_counter < 5)
BEGIN
INSERT INTO mytable VALUES (@start_val + 1, "new row")
PRINT (@start_val)
SET @start_val = @start_val + 1
SET @loop_counter = @loop_counter + 1
END
GO
现在执行起始值为 1 的预存程序,如下所示:
EXECUTE InsertRows 1
GO
执行后会打印五个@start_val值:0、1、2、3和4。使用下面的陈述式从mytable中选择所有的数据列:
SELECT *
FROM mytable
GO
在执行 SELECT 陈述式后,会出现如下的输出:
column1 column2
-------- ----------
1 new row
2 new row
3 new row
4 new row
5 new row
当结束预存程序后,@loop_counter和@start_val就无法再被存取。先使用下面的 T-SQL 陈述式尝试打印:
PRINT (@loop_counter)
PRINT (@start_val)
GO
就会得到这样的错误讯息:
服务器:讯息 137,层级 15,状态 2,行 1
必须宣告变量 '@loop_counter'。
服务器:讯息 137,层级 15,状态 1,行 2
必须宣告变量 '@start_val'。
执行批次陈述式操作时,此变量范围的规则也适用。一旦宣告关键词 GO(表示批次陈述式结束),批次陈述式所宣告的区域变量将不能再被使用,区域变量的范围仅限该批次陈述式使用。以下的预存过程调用能让您了解这个规则:
USE Northwind
GO
DECLARE @price money
EXECUTE GetUnitPrice 77, @unit_price = @price OUTPUT
PRINT CONVERT(varchar(6), @price)
GO
PRINT CONVERT(varchar(6), @price)
GO
第一个 PRINT 陈述式打印了批次操作中的区域变量@price;第二个 PRINT 陈述式企图在批次操作结束后,打印此区域变量,这时就会回传如下的错误讯息:
13.00
服务器:讯息 137,层级 15,状态 2,行 1
必须宣告变量 '@price'。
第一个打印陈述式成功的执行(打印出值 13.00)。
您可能想在预存程序中使用不只一条 T-SQL 陈述式,如 BEGIN TRANSACTION、COMMIT 和 ROLLBACK 这些陈述式,操作的方法是要先将这些陈述式群组成为一个单位的交易,使用的细节请参阅 第十九章 。
使用 RETURN
在任何时刻使用 RETURN 关键词都可以无条件退出预存程序以回到呼叫程序,也可用于退出批次操作等等。当 RETURN 执行时,预存程序执行到该点即停止执行,并回到呼叫程序中的下一个陈述式,RETURN 也可传回整数值。
首先,让我们看一个使用 RETURN 从预存程序中退出的范例。您将修改之前的GetUnitPrice程序来检查是否提供输入值,如果没有,打印此信息给使用者并回到呼叫程序。要达成此目的,请将输入参数默认值定义为 NULL,然后检查程序中的值是否为 NULL,这表示没有输入任何值。以下是这个程序的程序代码:
USE Northwind
GO
IF EXISTS (SELECT name
FROM sysobjects
WHERE name = "GetUnitPrice" AND
type = "P")
DROP PROCEDURE GetUnitPrice
GO