存储过程可以具有零个或多个参数。 它还可以返回一个值。 使用 SQL Server Native Client OLE DB 访问接口时,可以通过以下方法传递存储过程的参数:
对数据值进行硬编码。
使用参数标记(?)指定参数,将程序变量绑定到参数标记,然后将数据值置于程序变量中。
注释
将命名参数与 OLE DB 配合使用调用 SQL Server 存储过程时,参数名称必须以“@”字符开头。 这是 SQL Server 特有的限制。 SQL Server Native Client OLE DB 提供程序比 MDAC 更严格地强制实施此限制。
为了支持参数, ICommandWithParameters 接口在命令对象上公开。 若要使用参数,使用者首先通过调用 ICommandWithParameters::SetParameterInfo 方法(或选择性地准备调用 GetParameterInfo 方法的调用语句)来描述提供程序的参数。 然后,使用者创建一个访问器,该访问器指定缓冲区的结构,并将参数值置于此缓冲区中。 最后,它将访问器的句柄和指向要 执行的缓冲区的指针传递。 在以后调用 Execute 时,使用者在缓冲区中放置新的参数值,并使用访问器句柄和缓冲区指针调用 Execute 。
使用参数调用临时存储过程的命令必须先调用 ICommandWithParameters::SetParameterInfo 来定义参数信息,然后才能成功准备命令。 这是因为临时存储过程的内部名称不同于客户端使用的外部名称,SQLOLEDB 无法查询系统表以确定临时存储过程的参数信息。
以下是参数绑定过程中的步骤:
在 DBPARAMBINDINFO 结构数组中填写参数信息;即参数名称、参数名称、参数数据类型或标准数据类型名称的特定于提供程序的名称,等等。 数组中的每个结构都描述了一个参数。 然后,此数组将传递给 SetParameterInfo 方法。
调用 ICommandWithParameters::SetParameterInfo 方法来描述提供程序的参数。 SetParameterInfo 指定每个参数的本机数据类型。 SetParameterInfo 参数为:
要为其设置类型信息的参数数。
要为其设置类型信息的参数序号数组。
DBPARAMBINDINFO 结构的数组。
使用 IAccessor::CreateAccessor 命令创建参数访问器。 访问器指定缓冲区的结构,并将参数值置于缓冲区中。 CreateAccessor 命令从一组绑定创建访问器。 使用者通过使用 DBBINDING 结构的数组来描述这些绑定。 每个绑定将单个参数关联到使用者的缓冲区,并包含如下信息:
绑定应用到的参数序号。
绑定的内容(数据值、其长度和状态)。
缓冲区中每个部分的偏移量。
数据值的长度和类型,因为它存在于使用者的缓冲区中。
访问器由其句柄标识,该句柄的类型为 HACCESSOR。 CreateAccessor 方法返回此句柄。 每当使用者使用完访问器时,使用者都必须调用 ReleaseAccessor 方法以释放它持有的内存。
当使用者调用方法(如 ICommand::Execute)时,它会将句柄传递给访问器和指向缓冲区本身的指针。 提供程序使用此访问器来确定如何传输缓冲区中包含的数据。
填写 DBPARAMS 结构。 从中获取输入参数值的使用者变量,并在运行时将输出参数值传递给 DBPARAMS 结构中的 ICommand::Execute 。 DBPARAMS 结构包括三个元素:
一个指针,指向提供程序从中检索输入参数数据的缓冲区,以及提供程序根据访问器句柄指定的绑定返回输出参数数据的缓冲区。
缓冲区中的参数集数。
在步骤 3 中创建的访问器句柄。
使用 ICommand::Execute 执行命令。
调用存储过程的方法
在 SQL Server 中执行存储过程时,SQL Server Native Client OLE DB 访问接口支持:
ODBC CALL 转义序列。
远程过程调用 (RPC) 转义序列。
Transact-SQL EXECUTE 语句。
ODBC CALL 转义序列
如果知道参数信息,请调用 ICommandWithParameters::SetParameterInfo 方法来描述提供程序的参数。 否则,当 ODBC CALL 语法用于调用存储过程时,提供程序将调用帮助程序函数来查找存储过程参数信息。
如果不确定参数信息(参数元数据),建议使用 ODBC CALL 语法。
使用 ODBC CALL 转义序列调用过程的一般语法为:
{[?=]callprocedure_name[[parameter][,[parameter]]...)]}
例如:
{call SalesByCategory('Produce', '1995')}
RPC 转义序列
RPC 转义序列类似于调用存储过程的 ODBC CALL 语法。 如果要多次调用该过程,RPC 转义序列在调用存储过程的三种方法中提供了最佳性能。
当 RPC 转义序列用于执行存储过程时,提供程序不会调用任何帮助程序函数来确定参数信息(与 ODBC CALL 语法一样)。 RPC 语法比 ODBC CALL 语法更简单,因此命令分析速度更快,从而提高性能。 在这种情况下,需要通过执行 ICommandWithParameters::SetParameterInfo 来提供参数信息。
RPC 转义序列要求你具有返回值。 如果存储过程未返回值,则服务器默认返回 0。 此外,不能在存储过程上打开 SQL Server 游标。 存储过程是隐式准备的,对 ICommandPrepare::P repare 的 调用将失败。 由于无法准备 RPC 调用,因此无法查询列元数据;IColumnsInfo::GetColumnInfo 和 IColumnsRowset::GetColumnsRowset 将返回DB_E_NOTPREPARED。
如果知道所有参数元数据,则建议使用 RPC 转义序列来执行存储过程。
这是用于调用存储过程的 RPC 转义序列的示例:
{rpc SalesByCategory}
有关演示 RPC 转义序列的示例应用程序,请参阅执行存储过程(使用 RPC 语法)和进程返回代码和输出参数 (OLE DB)。
Transact-SQL EXECUTE 语句
ODBC CALL 转义序列和 RPC 转义序列是调用存储过程而不是 EXECUTE 语句的首选方法。 SQL Server Native Client OLE DB 访问接口使用 SQL Server 的 RPC 机制来优化命令处理。 此 RPC 协议通过避免在服务器上进行大量参数处理和语句分析来提高性能。
这是 Transact-SQL EXECUTE 语句的示例:
EXECUTE SalesByCategory 'Produce', '1995'