执行存储过程(数据库引擎)

若要执行存储过程,可以使用 Transact-SQL EXECUTE 语句。如果存储过程是批处理中的第一条语句,那么不使用 EXECUTE 关键字也可以执行存储过程。

执行系统存储过程

系统存储过程以字符 sp_ 开头。它们物理上存储在资源数据库中,但逻辑上出现在 SQL Server 实例的每个系统定义数据库和用户定义数据库的 sys 架构中。可以从任何数据库执行系统存储过程,而不必完全限定存储过程名称。非架构限定名称可以是由一个部分组成的名称(如 sp_someproc),也可以是由三个部分组成的名称(如 somedb..sp_someproc),第二部分是架构名称,这里并未指定。

建议使用 sys 架构名称对所有系统存储名称进行限定,以防止名称冲突。以下示例说明执行系统存储过程的推荐方法。

EXEC sys.sp_who;

下列示例说明执行系统存储过程的向后兼容方法。

注意注意

SQL Server 的未来版本中将删除下列执行系统存储过程的方法。请避免在新的开发工作中使用这些方法,并计划修改当前使用它们的应用程序。

EXEC sp_who;
EXEC master.dbo.sp_who;
EXEC mydatabase..sp_who;
EXEC dbo.sp_who;
EXEC mydatabase.dbo.sp_who;

数据库排序规则匹配

SQL Server 2008 与系统过程名称匹配时调用数据库排序规则。因此,在应用程序中应始终使用系统过程名称的正确大小写形式。例如,如果在具有区分大小写的排序规则的数据库上下文中执行,以下代码将失败:

exec SP_heLP; -- Will fail to resolve because SP_heLP does not equal sp_help 

使用 sys.system_objectssys.system_parameters 目录视图可以显示确切的系统存储过程名称。

执行系统扩展存储过程

系统扩展存储过程以字符 xp_ 开头。它们物理上存储在资源数据库中,但逻辑上出现在 SQL Server 实例的每个系统定义数据库和用户定义数据库的 sys 架构中。以下示例说明执行系统扩展存储过程的推荐方法。

EXEC sys.xp_subdirs 'c:\';

执行用户定义存储过程

执行用户定义存储过程(不管是在批处理中还是在模块内,例如在用户定义存储过程或函数中)时,极力建议至少用架构名称限定存储过程名称。

以下示例说明执行用户定义存储过程的推荐方法。

USE AdventureWorks2008R2;
GO
EXEC dbo.uspGetEmployeeManagers 50;

-或-

EXEC AdventureWorks2008R2.dbo.uspGetEmployeeManagers 50;
GO

如果指定了非限定用户定义存储过程,则数据库引擎 按以下顺序搜索此过程:

  • 当前数据库的 sys 架构。

  • 调用方的默认架构(如果在批处理或动态 SQL 中执行)。或者,如果非限定的过程名称出现在另一个过程定义的主体中,则接着搜索包含这一过程的架构。有关默认架构的详细信息,请参阅用户架构分离

  • 当前数据库中的 dbo 架构。

重要说明重要提示

如果用户创建的存储过程与系统存储过程同名,在使用非架构限定的名称引用的情况下,将永远不会执行用户创建的存储过程。有关详细信息,请参阅创建存储过程(数据库引擎)

指定参数

如果将存储过程编写为可以接受参数值,那么可以提供参数值。

提供的值必须为常量或变量,不能将函数名称指定为参数值。变量可以是用户定义变量或系统变量,如 @@spid。

下列示例说明如何将参数值传递给存储过程 uspGetWhereUsedProductID。此过程需要两个输入参数值:一个产品 ID 和一个日期。下列示例说明了如何将参数作为常量和变量进行传递,以及如何使用变量传递函数值。

USE AdventureWorks2008R2;
GO
-- Passing values as constants.
EXEC dbo.uspGetWhereUsedProductID 819, '20050225';
GO
-- Passing values as variables.
DECLARE @ProductID int, @CheckDate datetime;
SET @ProductID = 819;
SET @CheckDate = '20050225';
EXEC dbo.uspGetWhereUsedProductID @ProductID, @CheckDate;
GO
-- Try to use a function as a parameter value.
-- This produces an error message.
EXEC dbo.uspGetWhereUsedProductID 819, GETDATE();
GO
-- Passing the function value as a variable.
DECLARE @CheckDate datetime;
SET @CheckDate = GETDATE();
EXEC dbo.uspGetWhereUsedProductID 819, @CheckDate;
GO

如果希望以不同的顺序(而非参数在存储过程中的定义顺序)来指定参数,则需为参数命名。有关详细信息,请参阅指定参数名称

若要指定参数必须将一个值返回到调用程序,请使用 OUTPUT 关键字。有关详细信息,请参阅指定参数的方向

指定参数顺序

如果以 **@parameter =**value 格式提供多个参数,则可以按任何顺序提供参数。还可以省略那些已提供默认值的参数。如果以 **@parameter =**value 格式提供一个参数,则必须按此格式提供所有的后续参数。如果不以 **@parameter =**value 格式提供参数,则必须按照 CREATE PROCEDURE 语句中给出的顺序提供参数。

执行存储过程时,服务器将拒绝所有未包含在过程创建期间的参数列表中的参数。如果参数名称不匹配,通过引用传递(显式传递参数名称)的任何参数都不会被接受。

使用参数的默认值

虽然可以省略已提供默认值的参数,但只能截断参数列表。例如,如果一个存储过程有五个参数,那么您可以省略第四个和第五个参数,但不能跳过第四个参数而仍然包含第五个参数,除非以 **@parameter =**value 格式提供参数。

如果在存储过程中定义了参数的默认值,那么下列情况下将使用默认值:

  • 执行存储过程时未指定参数值。

  • 将 DEFAULT 关键字指定为参数值。