调用存储过程

适用于:SQL Server Azure SQL 数据库 Azure SQL 托管实例 Azure Synapse Analytics Analytics 平台系统(PDW)

SQL Server Native Client ODBC 驱动程序支持 ODBC CALL 转义序列和 Transact-SQLEXECUTE 语句来执行存储过程;ODBC CALL 转义序列是首选方法。 使用 ODBC 语法,应用程序可以检索存储过程的返回代码,SQL Server Native Client ODBC 驱动程序也经过优化,以使用最初开发的协议在运行 SQL Server 的计算机之间发送远程过程(RPC)调用。 此 RPC 协议通过避免在服务器上进行大量参数处理和语句分析来提高性能。

注意

将命名参数与 ODBC 配合使用调用 SQL Server 存储过程时(有关详细信息,请参阅 “按名称绑定参数”(命名参数)),参数名称必须以“@”字符开头。 这是 SQL Server 特有的限制。 SQL Server Native Client ODBC 驱动程序比Microsoft数据访问组件(MDAC)更严格地强制实施此限制。

调用过程的 ODBC CALL 转义序列是:

{[?=]callprocedure_name[([parameter][[parameter]]]...]]}

其中procedure_name指定过程的名称,参数指定过程参数。 只有使用 ODBC CALL 转义序列的语句中才支持命名参数。

一个过程可以有零个或多个参数。 它还可以返回值(如语法开头的可选参数标记 ?= 所示)。 如果参数是输入或输入/输出参数,它可以是文字或参数标记。 如果参数是输出参数,它必须是参数标记,因为输出是未知的。 在执行过程调用语句之前,参数标记必须与 SQLBindParameter 绑定。

过程调用的输入和输入/输出参数可以省略。 如果使用括号但不带任何参数调用过程,驱动程序将指示数据源使用第一个参数的默认值。 例如:

{call procedure_name( )}

如果该过程不具有任何参数,则它可能失败。 如果不带括号调用过程,驱动程序将不发送任何参数值。 例如:

{call procedure_name}

可以为过程调用中的输入和输入/输出参数指定文字。 例如,过程 InsertOrder 具有五个输入参数。 以下对 InsertOrder 的调用省略了第一个参数,为第二个参数提供文字,为第三、第四、第五个参数使用参数标记。 (按顺序对参数编号,从值 1 开始。)

{call InsertOrder(, 10, ?, ?, ?)}  

请注意如果省略一个参数,分隔该参数与其他参数的逗号必须保留。 如果省略输入参数或输入/输出参数,过程会使用该参数的默认值。 指定输入参数或输入/输出参数默认值的其他方式包括:将绑定到该参数的长度/指示器缓冲区的值设置为 SQL_DEFAULT_PARAM,或使用 DEFAULT 关键字。

如果省略输入/输出参数,或者如果为该参数提供文字,驱动程序将放弃输出值。 同样,如果省略过程返回值的参数标记,驱动程序将放弃返回值。 最后一点,如果应用程序为不返回值的过程指定返回值参数,驱动程序将绑定到该参数的长度/指示器缓冲区的值设置为 SQL_NULL_DATA。

CALL 语句中的分隔符

默认情况下,SQL Server Native Client ODBC 驱动程序还支持特定于 ODBC { CALL } 转义序列的兼容性选项。 该驱动程序接受仅用一对双引号分隔整个存储过程名称的 CALL 语句:

{ CALL "master.dbo.sp_who" }  

默认情况下,SQL Server Native Client ODBC 驱动程序还接受遵循 ISO 规则的 CALL 语句,并将每个标识符括在双引号中:

{ CALL "master"."dbo"."sp_who" }  

但是,当使用默认设置运行时,SQL Server Native Client ODBC 驱动程序不支持使用任一形式的带引号的标识符,这些标识符包含 ISO 标准在标识符中未指定为合法字符的标识符。 例如,驱动程序无法使用带带引号的标识符的 CALL 语句访问名为 “My.Proc” 的存储过程:

{ CALL "MyDB"."MyOwner"."My.Proc" }  

此语句将被该驱动程序解释为:

{ CALL MyDB.MyOwner.My.Proc }  

服务器引发名为 MyDB 的链接服务器不存在的错误。

使用带方括号的标识符时则不存在此问题,此语句可以正确地进行解释:

{ CALL [MyDB].[MyOwner].[My.Table] }  

另请参阅

运行存储过程