SQLBindParameter 函数

一致性
引入的版本:ODBC 2.0 标准符合性:ODBC

总结
SQLBindParameter 将缓冲区绑定到 SQL 语句中的参数标记。 SQLBindParameter 支持绑定到 Unicode C 数据类型,即使基础驱动程序不支持 Unicode 数据。

注意

此函数替换 ODBC 1.0 函数 SQLSetParam。 有关详细信息,请参阅“注释”。

语法

  
SQLRETURN SQLBindParameter(  
      SQLHSTMT        StatementHandle,  
      SQLUSMALLINT    ParameterNumber,  
      SQLSMALLINT     InputOutputType,  
      SQLSMALLINT     ValueType,  
      SQLSMALLINT     ParameterType,  
      SQLULEN         ColumnSize,  
      SQLSMALLINT     DecimalDigits,  
      SQLPOINTER      ParameterValuePtr,  
      SQLLEN          BufferLength,  
      SQLLEN *        StrLen_or_IndPtr);  

参数

StatementHandle
[输入]语句句柄。

ParameterNumber
[输入]参数编号,按递增参数顺序按顺序排序,从 1 开始。

InputOutputType
[输入] 参数的类型。 有关详细信息,请参阅“Comments”中的“InputOutputType 参数”。

ValueType
[输入]参数的 C 数据类型。 有关详细信息,请参阅“注释”中的“ValueType 参数”。

ParameterType
[输入]参数的 SQL 数据类型。 有关详细信息,请参阅“Comments”中的“ParameterType 参数”。

ColumnSize
[输入]相应参数标记的列或表达式的大小。 有关详细信息,请参阅“注释”中的“ColumnSize 参数”。

如果应用程序将在 64 位 Windows 操作系统上运行,请参阅 ODBC 64 位信息

DecimalDigits
[输入]相应参数标记的列或表达式的十进制数字。 有关列大小的详细信息,请参阅 列大小、小数位数、传输八进制数长度和显示大小

ParameterValuePtr
[延迟输入]指向参数数据的缓冲区的指针。 有关详细信息,请参阅“Comments”中的“ParameterValuePtr 参数”。

BufferLength
[输入/输出]ParameterValuePtr 缓冲区的长度(以字节为单位)。 有关详细信息,请参阅“注释”中的“BufferLength 参数”。

如果应用程序将在 64 位操作系统上运行,请参阅 ODBC 64 位信息

StrLen_or_IndPtr
[延迟输入]指向参数长度缓冲区的指针。 有关详细信息,请参阅“注释”中的“StrLen_or_IndPtr 参数”。

返回

SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_ERROR 或SQL_INVALID_HANDLE。

诊断

当 SQLBindParameter 返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,可以通过使用 handleType of SQL_HANDLE_STMT 和 StatementHandle 句柄调用 SQLGetDiagRec 来获取关联的 SQLSTATE 值。 下表列出了 SQLBindParameter 通常返回的 SQLSTATE 值,并解释此函数上下文中的每个值;表示法“(DM)”位于驱动程序管理器返回的 SQLSTATE 的说明之前。 除非另有说明,否则与每个 SQLSTATE 值关联的返回代码SQL_ERROR。

SQLSTATE 错误 说明
01000 常规警告 特定于驱动程序的信息性消息。 (函数返回SQL_SUCCESS_WITH_INFO。)
07006 受限数据类型属性冲突 ValueType 参数标识的数据类型不能转换为 ParameterType 参数标识的数据类型。 请注意,在执行时 SQLExecDirectSQLExecuteSQLPutData 可能会返回此错误,而不是由 SQLBindParameter 返回
07009 描述符索引无效 (DM) 为参数 ParameterNumber 指定的值小于 1。
HY000 常规错误 发生错误:没有特定的 SQLSTATE,也没有定义特定于实现的 SQLSTATE。 *MessageText 缓冲区中 SQLGetDiagRec 返回的错误消息描述错误及其原因。
HY001 内存分配错误 驱动程序无法分配支持执行或完成函数所需的内存。
HY003 应用程序缓冲区类型无效 参数 ValueType 指定的值不是有效的 C 数据类型或SQL_C_DEFAULT。
HY004 SQL 数据类型无效 为参数 ParameterType 指定的值既不是有效的 ODBC SQL 数据类型标识符,也不是驱动程序支持的特定于驱动程序的 SQL 数据类型标识符。
HY009 参数值无效 (DM) 参数 ParameterValuePtr 为空指针, 参数StrLen_or_IndPtr 为 null 指针,参数 InputOutputType 未SQL_PARAM_OUTPUT。

(DM) SQL_PARAM_OUTPUT,其中参数 ParameterValuePtr 为 null 指针,C 类型为 char 或 binary,BufferLength (cbValueMax) 大于 0。
HY010 函数序列错误 (DM) 为与 StatementHandle 关联的连接句柄调用异步执行函数。 调用 SQLBindParameter,此异步函数仍在执行。

(DM) 为 StatementHandle 调用了 SQLExecuteSQLExecDirectSQLMoreResults,并返回了SQL_PARAM_DATA_AVAILABLE。 在检索所有流式处理参数的数据之前调用此函数。

(DM) 为 StatementHandle 调用异步执行函数,并在调用此函数时仍在执行。

(DM) 为 StatementHandle 调用了 SQLExecuteSQLExecDirectSQLBulkOperationsSQLSetPos,并返回了SQL_NEED_DATA。 在为所有数据执行参数或列发送数据之前调用此函数。
HY013 内存管理错误 无法处理函数调用,因为基础内存对象无法访问,可能是因为内存条件低。
HY021 不一致的描述符信息 在一致性检查期间检查的描述符信息不一致。 (请参阅 中的 “一致性检查”部分SQLSetDescField.)

为参数 DecimalDigits 指定的值超出了 ParameterType 参数所指定的 SQL 数据类型列的数据源支持的值范围。
HY090 字符串或缓冲区长度无效 (DM) BufferLength 中的值小于 0。 (请参阅SQL_DESC_DATA_PTR 字段的说明SQLSetDescField.)
HY104 精度或小数位数值无效 为参数 ColumnSizeDecimalDigits 指定的值超出了由 ParameterType 参数指定的 SQL 数据类型列的数据源支持的值范围。
HY105 参数类型无效 (DM) 为参数 InputOutputType 指定的值无效。 (请参阅“注释”。
HY117 连接因未知事务状态而挂起。 仅允许断开连接和只读函数。 (DM) 有关挂起状态的详细信息,请参阅 SQLEndTran 函数
HYC00 未实现可选功能 驱动程序或数据源不支持由为参数 ValueType 指定的值与为参数 ParameterType 指定的特定于驱动程序的值的组合指定的转换。

为参数 ParameterType 指定的值是驱动程序支持的 ODBC 版本的有效 ODBC SQL 数据类型标识符,但驱动程序或数据源不支持。

驱动程序仅支持 ODBC 2。x 和参数 ValueType 是下列值之一:

SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT

以及附录 D 中 C 数据类型中列出的所有间隔 C 数据类型:数据类型。

驱动程序仅支持 3.50 之前的 ODBC 版本,并且参数 ValueType SQL_C_GUID。
HYT01 超过连接超时时间 在数据源响应请求之前,连接超时期限已过期。 连接超时期限通过 SQLSetConnectAttr 设置,SQL_ATTR_CONNECTION_TIMEOUT。
IM001 驱动程序不支持此函数 (DM) 与 StatementHandle 关联的驱动程序不支持该函数。

注释

应用程序调用 SQLBindParameter 以绑定 SQL 语句中的每个参数标记。 绑定一直有效,直到应用程序再次调用 SQLBindParameter、使用SQL_RESET_PARAMS选项调用 SQLFreeStmt,或调用 SQLSetDDescField 将 APD 的SQL_DESC_COUNT标头字段设置为 0。

有关参数的详细信息,请参阅语句参数。 有关参数数据类型和参数标记的详细信息,请参阅 附录 C:SQL 语法中的参数数据类型参数标记

ParameterNumber 参数

如果调用 SQLBindParameter 中的 ParameterNumber 大于 SQL_DESC_COUNT 的值,则调用 SQLSetDescField 将SQL_DESC_COUNT的值增加到 ParameterNumber

InputOutputType 参数

InputOutputType 参数指定参数的类型。 此参数设置 IPD 的SQL_DESC_PARAMETER_TYPE字段。 不调用过程(如 INSERT 语句)的 SQL 语句中的所有参数都是输入参数。 过程调用中的参数可以是输入、输入/输出或输出参数。 (应用程序调用 SQLProcedureColumns 在过程调用中确定参数的类型;不能确定其类型的参数假定为输入参数。

InputOutputType 参数为以下其中一个值 :

  • SQL_PARAM_INPUT。 该参数在 SQL 语句中标记一个不调用过程(如 INSERT 语句)的参数,或在过程中标记输入参数。 例如,INSERT INTO Employee VALUES(?, ?, ?)中的参数是输入参数,而 {call AddEmp(?, ?, ?)} 中的参数可以是输入参数,但不一定是输入参数。

    执行语句时,驱动程序会将参数的数据发送到数据源;*ParameterValuePtr 缓冲区必须包含有效的输入值,或者 *StrLen_or_IndPtr 缓冲区必须包含SQL_NULL_DATA、SQL_DATA_AT_EXEC或SQL_LEN_DATA_AT_EXEC宏的结果。

    如果应用程序无法在过程调用中确定参数的类型,它将 InputOutputType 设置为 SQL_PARAM_INPUT;如果数据源返回参数的值,驱动程序将放弃它。

  • SQL_PARAM_INPUT_OUTPUT。 该参数在过程中标记输入/输出参数。 例如,{call GetEmpDept(?)} 中的参数是接受员工姓名并返回员工部门名称的输入/输出参数。

    执行语句时,驱动程序会将参数的数据发送到数据源;*ParameterValuePtr 缓冲区必须包含有效的输入值,或者 *StrLen_or_IndPtr 缓冲区必须包含SQL_NULL_DATA、SQL_DATA_AT_EXEC或SQL_LEN_DATA_AT_EXEC宏的结果。 执行语句后,驱动程序会将参数的数据返回到应用程序;如果数据源未返回输入/输出参数的值,驱动程序会将 *StrLen_or_IndPtr 缓冲区设置为SQL_NULL_DATA。

    注意

    当 ODBC 1.0 应用程序在 ODBC 2.0 驱动程序中调用 SQLSetParam 时,驱动程序管理器会将它转换为对 SQLBindParameter 的调用其中 InputOutputType 参数设置为SQL_PARAM_INPUT_OUTPUT。

  • SQL_PARAM_OUTPUT。 该参数标记过程中过程或输出参数的返回值;在任一情况下,这些参数称为 输出参数。 例如,{?=call GetNextEmpID} 中的参数是返回下一个员工 ID 的输出参数。

    执行语句后,驱动程序会将参数的数据返回到应用程序,除非 ParameterValuePtrStrLen_or_IndPtr 参数都是空指针,在这种情况下,驱动程序将放弃输出值。 如果数据源未返回输出参数的值,驱动程序会将 *StrLen_or_IndPtr 缓冲区设置为SQL_NULL_DATA。

  • SQL_PARAM_INPUT_OUTPUT_STREAM。 指示应流式传输输入/输出参数。 SQLGetData 可以在部件中读取参数值。 BufferLength 将被忽略,因为缓冲区长度将在 SQLGetData 调用时确定。 StrLen_or_IndPtr缓冲区的值必须包含SQL_NULL_DATA、SQL_DEFAULT_PARAM、SQL_DATA_AT_EXEC或SQL_LEN_DATA_AT_EXEC宏的结果。 如果参数将在输出中流式传输,则必须在输入时将其绑定为数据执行时 (DAE) 参数。 ParameterValuePtr 可以是 SQLParamData 将作为用户定义的令牌返回的任何非 null 指针值,其值是使用 ParameterValuePtr 传递的输入和输出。 有关详细信息,请参阅 使用 SQLGetData 检索输出参数

  • SQL_PARAM_OUTPUT_STREAM。 与SQL_PARAM_INPUT_OUTPUT_STREAM相同,用于输出参数。 *输入时将忽略StrLen_or_IndPtr

下表列出了 InputOutputType 和 *StrLen_or_IndPtr的不同组合

InputOutputType *StrLen_or_IndPtr 业务成效 ParameterValuePtr 备注
SQL_PARAM_INPUT SQL_LEN_DATA_AT_EXEC(len) 或SQL_DATA_AT_EXEC 部件中的输入 ParameterValuePtr 可以是 SQLParamData 将作为用户定义令牌返回的任何指针值,其值是使用 ParameterValuePtr 传递的。
SQL_PARAM_INPUT 不SQL_LEN_DATA_AT_EXEC(len)或SQL_DATA_AT_EXEC 输入绑定缓冲区 ParameterValuePtr 是输入缓冲区的地址。
SQL_PARAM_OUTPUT 在输入时忽略。 输出绑定缓冲区 ParameterValuePtr 是输出缓冲区的地址。
SQL_PARAM_OUTPUT_STREAM 在输入时忽略。 流式处理输出 ParameterValuePtr 可以是任何指针值,SQLParamData 将作为用户定义令牌返回,其值是使用 ParameterValuePtr 传递的。
SQL_PARAM_INPUT_OUTPUT SQL_LEN_DATA_AT_EXEC(len) 或SQL_DATA_AT_EXEC 部件和输出绑定缓冲区中的输入 ParameterValuePtr 是输出缓冲区的地址,SQLParamData 也会将其作为用户定义令牌返回,其值是使用 ParameterValuePtr 传递的。
SQL_PARAM_INPUT_OUTPUT 不SQL_LEN_DATA_AT_EXEC(len)或SQL_DATA_AT_EXEC 输入绑定缓冲区和输出绑定缓冲区 ParameterValuePtr 是共享输入/输出缓冲区的地址。
SQL_PARAM_INPUT_OUTPUT_STREAM SQL_LEN_DATA_AT_EXEC(len) 或SQL_DATA_AT_EXEC 部件和流式输出中的输入 ParameterValuePtr 可以是任何非 null 指针值,SQLParamData 将作为用户定义的令牌返回,其值是使用 ParameterValuePtr 传递的输入和输出。

注意

当应用程序将输出或输入输出参数绑定到流式传输时,驱动程序必须确定允许哪些 SQL 类型。 驱动程序管理器不会为无效的 SQL 类型生成错误。

ValueType 参数

ValueType 参数指定参数的 C 数据类型。 此参数设置 APD 的SQL_DESC_TYPE、SQL_DESC_CONCISE_TYPE和SQL_DESC_DATETIME_INTERVAL_CODE字段。 这必须是附录 D:数据类型的 C 数据类型部分的值之一。

如果 ValueType 参数是间隔数据类型之一,则 APD 的 ParameterNumber 记录的SQL_DESC_TYPE字段设置为 SQL_INTERVAL,APD 的 SQL_DESC_CONCISE_TYPE 字段设置为简明的间隔数据类型,并将 ParameterNumber 记录的 SQL_DESC_DATETIME_INTERVAL_CODE 字段设置为特定间隔数据类型的子代码。 (请参阅 附录 D:数据类型。)默认间隔前导精度(2)和默认间隔秒精度(6),分别在 APD 的SQL_DESC_DATETIME_INTERVAL_PRECISION和SQL_DESC_PRECISION字段中设置用于数据。 如果默认精度不合适,应用程序应通过调用 SQLSetDescFieldSQLSetDescRec 显式设置描述符字段。

如果 ValueType 参数是日期/时间数据类型之一,则 APD 的 ParameterNumber 记录的SQL_DESC_TYPE字段设置为 SQL_DATETIME,则 APD 的 ParameterNumber 记录的 SQL_DESC_CONCISE_TYPE 字段设置为简洁的日期/时间 C 数据类型,ParameterNumber 记录的SQL_DESC_DATETIME_INTERVAL_CODE字段设置为特定日期/时间数据类型的子代码。 (请参阅 附录 D:数据类型。)

如果 ValueType 参数是SQL_C_NUMERIC数据类型,则默认精度(即驱动程序定义)和默认刻度(0),如 APD 的SQL_DESC_PRECISION和SQL_DESC_SCALE字段所设置,用于数据。 如果默认精度或小数位数不合适,应用程序应通过调用 SQLSetDescFieldSQLSetDescRec 显式设置描述符字段。

SQL_C_DEFAULT指定从使用 ParameterType 指定的 SQL 数据类型的默认 C 数据类型传输参数值。

还可以指定扩展的 C 数据类型。 有关详细信息,请参阅 ODBC 中的 C 数据类型

有关详细信息,请参阅 默认 C 数据类型将数据从 C 转换为 SQL 数据类型,以及 将数据从 SQL 转换为附录 D:数据类型中的 C 数据类型

ParameterType 参数

这必须是附录 D 的“SQL 数据类型”部分中列出的值之一:数据类型,或者它必须是特定于驱动程序的值。 此参数设置 IPD 的SQL_DESC_TYPE、SQL_DESC_CONCISE_TYPE和SQL_DESC_DATETIME_INTERVAL_CODE字段。

如果 ParameterType 参数是日期/时间标识符之一,则 IPD 的SQL_DESC_TYPE字段设置为SQL_DATETIME,IPD 的SQL_DESC_CONCISE_TYPE字段设置为简洁的日期/时间 SQL 数据类型,并将SQL_DESC_DATETIME_INTERVAL_CODE字段设置为适当的日期/时间子代码值。

如果 ParameterType 是间隔标识符之一,则 IPD 的SQL_DESC_TYPE字段设置为SQL_INTERVAL,IPD 的SQL_DESC_CONCISE_TYPE字段设置为简洁的 SQL 间隔数据类型,IPD 的SQL_DESC_DATETIME_INTERVAL_CODE字段设置为适当的间隔子代码。 IPD 的SQL_DESC_DATETIME_INTERVAL_PRECISION字段设置为间隔前导精度,SQL_DESC_PRECISION字段设置为间隔秒精度(如果适用)。 如果SQL_DESC_DATETIME_INTERVAL_PRECISION或SQL_DESC_PRECISION的默认值不适用,应用程序应通过调用 SQLSetDescField 显式设置它。 有关这些字段中的任何一个的详细信息,请参阅 SQLSetDescField

如果 ValueType 参数是SQL_NUMERIC数据类型,则会对数据使用SQL_DESC_PRECISION和SQL_DESC_SCALE字段中设置的默认精度(即驱动程序定义)和默认刻度(0)。 如果默认精度或小数位数不合适,应用程序应通过调用 SQLSetDescFieldSQLSetDescRec 显式设置描述符字段。

有关如何转换数据的信息,请参阅 附录 D:数据类型:将数据从 C 转换为 SQL 数据类型 ,以及 将数据从 SQL 转换为 C 数据类型

ColumnSize 参数

ColumnSize 参数指定与参数标记、该数据长度或两者相对应的列或表达式的大小。 此参数根据 SQL 数据类型( ParameterType 参数)设置 IPD 的不同字段。 以下规则适用于此映射:

  • 如果 ParameterType 是 SQL_CHAR、SQL_VARCHAR、SQL_LONGVARCHAR、SQL_BINARY、SQL_VARBINARY、SQL_LONGVARBINARY 或简明的 SQL 日期/时间间隔数据类型之一,则 IPD 的SQL_DESC_LENGTH字段设置为 ColumnSize 的值。 (有关详细信息,请参阅 附录 D:数据类型中的列大小、十进制数字、传输八进制长度和显示大小 部分。

  • 如果 ParameterType 是 SQL_DECIMAL、SQL_NUMERIC、SQL_FLOAT、SQL_REAL 或 SQL_DOUBLE,则 IPD 的SQL_DESC_PRECISION字段设置为 ColumnSize 的值

  • 对于其他数据类型, 将忽略 ColumnSize 参数。

有关详细信息,请参阅“StrLen_or_IndPtr参数”中的“传递参数值”和SQL_DATA_AT_EXEC。

DecimalDigits 参数

如果 ParameterType 为 SQL_TYPE_TIME、SQL_TYPE_TIMESTAMP、SQL_INTERVAL_SECOND、SQL_INTERVAL_DAY_TO_SECOND、SQL_INTERVAL_HOUR_TO_SECOND 或 SQL_INTERVAL_MINUTE_TO_SECOND,则 IPD 的SQL_DESC_PRECISION字段设置为 DecimalDigits。 如果 ParameterType 是SQL_NUMERIC或SQL_DECIMAL,则 IPD 的SQL_DESC_SCALE字段设置为 DecimalDigits。 对于所有其他数据类型, 将忽略 DecimalDigits 参数。

ParameterValuePtr 参数

ParameterValuePtr 参数指向调用 SQLExecuteSQLExecDirect包含参数的实际数据的缓冲区。 数据必须采用 ValueType 参数指定的窗体。 此参数设置 APD 的SQL_DESC_DATA_PTR字段。 只要 *StrLen_or_IndPtr SQL_NULL_DATA或SQL_DATA_AT_EXEC,应用程序就可以将 ParameterValuePtr 参数设置为 null 指针。 (这仅适用于输入或输入/输出参数。

如果 *StrLen_or_IndPtr 是SQL_LEN_DATA_AT_EXEC(length) 宏或SQL_DATA_AT_EXEC的结果,则 ParameterValuePtr 是与参数关联的应用程序定义的指针值。 它通过 SQLParamData 返回到应用程序。 例如, ParameterValuePtr 可能是非零标记,例如参数号、指向数据的指针,或指向应用程序用来绑定输入参数的结构的指针。 但是,请注意,如果参数是输入/输出参数, ParameterValuePtr 必须是指向将存储输出值的缓冲区的指针。 如果 SQL_ATTR_PARAMSET_SIZE 语句属性中的值大于 1,则应用程序可以使用 SQL_ATTR_PARAMS_PROCESSED_PTR 语句属性 和 ParameterValuePtr 参数指向的值。 例如, ParameterValuePtr 可能指向值数组,应用程序可能使用SQL_ATTR_PARAMS_PROCESSED_PTR指向的值从数组中检索正确的值。 有关详细信息,请参阅本节后面的“传递参数值”。

如果 InputOutputType 参数SQL_PARAM_INPUT_OUTPUT或SQL_PARAM_OUTPUT,ParameterValuePtr 指向驱动程序返回输出值的缓冲区。 如果过程返回一个或多个结果集,则在处理所有结果集/行计数之前,不能保证设置 *ParameterValuePtr 缓冲区。 如果在处理完成之前未设置缓冲区,则输出参数和返回值在 SQLMoreResults 返回SQL_NO_DATA之前不可用。 使用SQL_CLOSE选项调用 SQLCloseCursorSQLFreeStmt 将导致丢弃这些值。

如果 SQL_ATTR_PARAMSET_SIZE 语句属性中的值大于 1,ParameterValuePtr 指向数组。 单个 SQL 语句处理输入或输入/输出参数的输入值的完整数组,并返回输入/输出或输出参数的输出值数组。

BufferLength 参数

对于字符和二进制 C 数据,BufferLength 参数指定 *ParameterValuePtr 缓冲区(如果它是单个元素)或 *ParameterValuePtr 数组中元素的长度(如果SQL_ATTR_PARAMSET_SIZE语句属性中的值大于 1)。 此参数设置 APD 的SQL_DESC_OCTET_LENGTH记录字段。 如果应用程序指定多个值, 则 BufferLength 用于确定 *ParameterValuePtr 数组中值的位置,无论是在输入和输出上。 对于输入/输出和输出参数,它用于确定是否截断输出中的字符和二进制 C 数据:

  • 对于字符 C 数据,如果可返回的字节数大于或等于 BufferLength,则 *ParameterValuePtr 中的数据将被截断为 BufferLength,小于 null 终止字符的长度,并且由驱动程序以 null 结尾。

  • 对于二进制 C 数据,如果可返回的字节数大于 BufferLength,则 *ParameterValuePtr 中的数据将被截断为 BufferLength 字节。

对于所有其他类型的 C 数据, 将忽略 BufferLength 参数。 *ParameterValuePtr 缓冲区(如果它是单个元素)或 *ParameterValuePtr 数组中元素的长度(如果应用程序使用属性参数为 SQL_ATTR_PARAMSET_SIZE 调用 SQLSetStmtAttr 以指定每个参数的多个值)的长度假定为 C 数据类型的长度。

对于流式输出或流式传输的输入/输出参数,由于缓冲区长度是在 SQLGetData 中指定的,因此忽略 BufferLength 参数。

注意

当 ODBC 1.0 应用程序在 ODBC 3 中调用 SQLSetParam 时。x 驱动程序,驱动程序管理器将此转换为对 SQLBindParameter调用,其中 BufferLength 参数始终SQL_SETPARAM_VALUE_MAX。 因为如果 ODBC 3,驱动程序管理器将返回错误。x 应用程序将 BufferLength 设置为 odbc 3 SQL_SETPARAM_VALUE_MAX。x 驱动程序可用于确定 ODBC 1.0 应用程序何时调用它。

注意

SQLSetParam 中,应用程序指定 *ParameterValuePtr 缓冲区的长度,以便驱动程序可以返回字符或二进制数据的方式,以及应用程序向驱动程序发送字符或二进制参数值的数组的方式都是驱动程序定义的。

StrLen_or_IndPtr参数

StrLen_or_IndPtr参数指向调用 SQLExecuteSQLExecDirect包含下列项之一的缓冲区。 (此参数设置应用程序参数指针的SQL_DESC_OCTET_LENGTH_PTR和SQL_DESC_INDICATOR_PTR记录字段。

  • 存储在 *ParameterValuePtr 中的参数值的长度。 除字符或二进制 C 数据外,将忽略此项。

  • SQL_NTS。 参数值为以 null 结尾的字符串。

  • SQL_NULL_DATA。 参数值为 NULL。

  • SQL_DEFAULT_PARAM。 过程是使用参数的默认值,而不是从应用程序检索的值。 此值仅在 ODBC 规范语法中调用的过程有效,仅当 InputOutputType 参数SQL_PARAM_INPUT、SQL_PARAM_INPUT_OUTPUT或SQL_PARAM_INPUT_OUTPUT_STREAM时才有效。 当 *StrLen_or_IndPtr为SQL_DEFAULT_PARAM时,ValueType、ParameterTypeColumnSize、DecimalDigitsBufferLengthParameterValuePtr 参数将被忽略,仅用于定义输入/输出参数的输出参数值。

  • SQL_LEN_DATA_AT_EXEC(length) 宏的结果。 参数的数据将使用 SQLPutData 发送如果 ParameterType 参数SQL_LONGVARBINARY、SQL_LONGVARCHAR或特定于数据源的长数据类型,并且驱动程序为 SQLGetInfoSQL_NEED_LONG_DATA_LEN信息类型的返回“Y”,则长度为要为参数发送的数据字节数;否则,长度必须是非负值且将被忽略。 有关详细信息,请参阅本节后面的“传递参数值”。

    例如,若要指定在一个或多个调用中使用 SQLPutData 发送 10,000 字节的数据,对于SQL_LONGVARCHAR参数,应用程序会将 *StrLen_or_IndPtr 设置为 SQL_LEN_DATA_AT_EXEC(10000)。

  • SQL_DATA_AT_EXEC。 参数的数据将使用 SQLPutData 发送。 当 ODBC 1.0 应用程序调用 ODBC 3 时,将使用此值。x 驱动程序。 有关详细信息,请参阅本节后面的“传递参数值”。

如果 StrLen_or_IndPtr 为 null 指针,驱动程序假定所有输入参数值均为非 NULL,并且该字符和二进制数据以 null 结尾。 如果 InputOutputType 是SQL_PARAM_OUTPUT或SQL_PARAM_OUTPUT_STREAM且 ParameterValuePtrStrLen_or_IndPtr 都是 null 指针,驱动程序将放弃输出值。

注意

当参数的数据类型SQL_C_BINARY时,强烈建议不要为StrLen_or_IndPtr指定空指针。 为了确保驱动程序不会意外截断SQL_C_BINARY数据, StrLen_or_IndPtr 应包含指向有效长度值的指针。

如果 InputOutputType 参数SQL_PARAM_INPUT_OUTPUT、SQL_PARAM_OUTPUT、SQL_PARAM_INPUT_OUTPUT_STREAM或SQL_PARAM_OUTPUT_STREAM,StrLen_or_IndPtr指向驱动程序返回SQL_NULL_DATA的缓冲区、可在 *ParameterValuePtr 中返回的字节数(不包括字符数据的 null 终止字节),或SQL_NO_TOTAL(如果无法确定可返回的字节数)。 如果过程返回一个或多个结果集,则在提取所有结果之前,不能保证设置 *StrLen_or_IndPtr 缓冲区。

如果 SQL_ATTR_PARAMSET_SIZE 语句属性中的值大于 1,StrLen_or_IndPtr指向 SQLLEN 值的数组。 这些值可以是本节前面列出的任何值,并使用单个 SQL 语句进行处理。

传递参数值

应用程序可以在 *ParameterValuePtr 缓冲区或对 SQLPutData 的一个或多个调用中传递参数的值。 使用 SQLPutData 传递数据的参数称为执行时的数据参数。 这些参数通常用于发送SQL_LONGVARBINARY和SQL_LONGVARCHAR参数的数据,并且可以与其他参数混合。

若要传递参数值,应用程序将执行以下步骤序列:

  1. 为每个参数调用 SQLBindParameter 以绑定参数值(ParameterValuePtr 参数)和长度/指示器(StrLen_or_IndPtr 参数)的缓冲区。 对于执行数据参数,ParameterValuePtr 是应用程序定义的指针值,例如参数编号或指向数据的指针。 该值稍后将返回,可用于标识参数。

  2. 在 *ParameterValuePtr 和 *StrLen_or_IndPtr 缓冲区中放置输入和输出参数的值:

    • 对于普通参数,应用程序将参数值放在 *ParameterValuePtr 缓冲区中,并将该值的长度放在 *StrLen_or_IndPtr 缓冲区中。 有关详细信息,请参阅 “设置参数值”。

    • 对于执行数据参数,应用程序会将 SQL_LEN_DATA_AT_EXEC(length) 宏(调用 ODBC 2.0 驱动程序时)的结果置于 *StrLen_or_IndPtr 缓冲区中。

  3. 调用 SQLExecuteSQLExecDirect 来执行 SQL 语句。

    • 如果没有执行时的数据参数,则该过程已完成。

    • 如果存在任何执行时的数据参数,该函数将返回SQL_NEED_DATA。

  4. 调用 SQLParamData 检索 SQLBindParameter ParameterValuePtr 参数中指定的应用程序定义值,以便处理要处理的第一个数据执行参数。 SQLParamData 返回SQL_NEED_DATA。

    注意

    尽管数据执行参数类似于执行时的数据列,但 SQLParamData 返回的值对于每个列都是不同的。 数据执行参数是 SQL 语句中的参数,在使用 SQLExecDirect 或 SQLExecute 执行语句时,将使用 SQLPutData 发送数据。 它们与 SQLBindParameter 绑定。 SQLParamData 返回的值是在 ParameterValuePtr 参数中传递给 SQLBindParameter指针值。 执行时的数据列是行集中的列,当使用 SQLBulkOperations 更新或添加行或使用 SQLSetPos 更新时,将使用 SQLPutData 发送数据。 它们与 SQLBindCol 绑定。 SQLParamData 返回的值是正在处理的 *TargetValuePtr 缓冲区(由对 SQLBindCol 的调用设置)中的行的地址。

  5. 调用 SQLPutData 一次或多次以发送参数的数据。 如果数据值大于 SQLPutData 中指定的 *ParameterValuePtr 缓冲区,则仅当将字符 C 数据发送到具有字符、二进制或数据源特定数据类型的列,或者向具有字符、二进制或数据源特定数据类型的列发送二进制 C 数据时,才允许对同一参数的 SQLPutData 进行多次调用 二进制或特定于数据源的数据类型。

  6. 再次调用 SQLParamData 以指示已为参数发送所有数据。

    • 如果存在更多执行时的数据参数, SQLParamData 将返回SQL_NEED_DATA和要处理的下一个执行时数据参数的应用程序定义值。 应用程序重复步骤 4 和 5。

    • 如果没有更多执行时的数据参数,则该过程已完成。 如果已成功执行语句, 则 SQLParamData 返回SQL_SUCCESS或SQL_SUCCESS_WITH_INFO;如果执行失败,则返回SQL_ERROR。 此时, SQLParamData 可以返回可由用于执行语句的函数返回的任何 SQLSTATE(SQLExecDirectSQLExecute)。

      应用程序检索语句生成的所有结果集后,*ParameterValuePtr 和 *StrLen_or_IndPtr 缓冲区中提供了任何输入/输出或输出参数的输出值。

调用 SQLExecuteSQLExecDirect 会将语句置于SQL_NEED_DATA状态。 此时,应用程序只能调用包含语句或与语句关联的连接句柄的 SQLCancelSQLGetDiagFieldSQLGetDiagRecSQLGetFunctionsSQLParamData 或 SQLPutData。 如果它调用任何其他具有语句的函数或与该语句关联的连接,该函数将返回 SQLSTATE HY010 (函数序列错误)。 当 SQLParamDataSQLPutData 返回错误时,该语句将保留SQL_NEED_DATA状态,SQLParamData 返回SQL_SUCCESS或SQL_SUCCESS_WITH_INFO或取消该语句。

如果应用程序在驱动程序仍需要数据执行参数时调用 SQLCancel ,驱动程序将取消语句执行;然后应用程序可以再次调用 SQLExecuteSQLExecDirect

检索流式输出参数

当应用程序将 InputOutputType 设置为SQL_PARAM_INPUT_OUTPUT_STREAM或SQL_PARAM_OUTPUT_STREAM时,输出参数值必须由一个或多个对 SQLGetData调用检索。 当驱动程序有流式输出参数值返回到应用程序时,它将返回SQL_PARAM_DATA_AVAILABLE以响应对以下函数的调用:SQLMoreResultsSQLExecuteSQLExecDirect。 应用程序调用 SQLParamData 来确定哪些参数值可用。

有关SQL_PARAM_DATA_AVAILABLE和流式输出参数的详细信息,请参阅 使用 SQLGetData 检索输出参数。

使用参数的数组

当应用程序准备具有参数标记并传入参数数组的语句时,可以通过两种不同的方式执行此参数。 一种方法是让驱动程序依赖于后端的数组处理功能,在这种情况下,具有参数数组的整个语句被视为一个原子单元。 Oracle 是支持数组处理功能的数据源的示例。 实现此功能的另一种方法是让驱动程序生成一批 SQL 语句,为参数数组中的每个参数集生成一个 SQL 语句,并执行批处理。 参数数组不能与 UPDATE WHERE CURRENT OF 语句一起使用。

处理参数数组时,单个结果集/行计数(每个参数集各有一个)可用,或者结果集/行计数可以汇总为一个。 SQLGetInfo 中的SQL_PARAM_ARRAY_ROW_COUNTS选项指示行计数是可用于每个参数集(SQL_PARC_BATCH),还是只提供一个行计数(SQL_PARC_NO_BATCH)。

SQLGetInfo 中的SQL_PARAM_ARRAY_SELECTS选项指示结果集是可用于每个参数集(SQL_PAS_BATCH),还是只有一个结果集可用(SQL_PAS_NO_BATCH)。 如果驱动程序不允许使用参数数组执行结果集生成语句,则SQL_PARAM_ARRAY_SELECTS返回SQL_PAS_NO_SELECT。

有关详细信息,请参阅 SQLGetInfo 函数

为了支持参数数组,SQL_ATTR_PARAMSET_SIZE语句属性设置为指定每个参数的值数。 如果字段大于 1,则 APD 的SQL_DESC_DATA_PTR、SQL_DESC_INDICATOR_PTR和SQL_DESC_OCTET_LENGTH_PTR字段必须指向数组。 每个数组的基数等于SQL_ATTR_PARAMSET_SIZE的值。

APD 的SQL_DESC_ROWS_PROCESSED_PTR字段指向包含已处理的参数集(包括错误集)的缓冲区。 处理每个参数集时,驱动程序会将新值存储在缓冲区中。 如果这是空指针,则不返回数字。 使用参数数组时,即使设置函数返回SQL_ERROR,APD SQL_DESC_ROWS_PROCESSED_PTR 字段指向的值也会填充。 如果返回SQL_NEED_DATA,则 APD SQL_DESC_ROWS_PROCESSED_PTR 字段指向的值将设置为正在处理的参数集。

绑定参数数组并 执行 UPDATE WHERE CURRENT OF 语句时发生的情况是驱动程序定义的。

Column-Wise 参数绑定

在按列绑定中,应用程序将单独的参数和长度/指示器数组绑定到每个参数。

若要使用按列绑定,应用程序首先将 SQL_ATTR_PARAM_BIND_TYPE 语句属性设置为SQL_PARAM_BIND_BY_COLUMN。 (这是默认值。对于要绑定的每个列,应用程序将执行以下步骤:

  1. 分配参数缓冲区数组。

  2. 分配长度/指示器缓冲区数组。

    注意

    如果使用列式绑定时,应用程序直接写入描述符,则可以将单独的数组用于长度和指示器数据。

  3. 使用以下参数调用 SQLBindParameter

    • ValueType 是参数缓冲区数组中单个元素的 C 类型。

    • ParameterType 是参数的 SQL 类型。

    • ParameterValuePtr 是参数缓冲区数组的地址。

    • BufferLength 是参数缓冲区数组中单个元素的大小。 当数据是固定长度的数据时,将忽略 BufferLength 参数。

    • StrLen_or_IndPtr 是长度/指示器数组的地址。

有关如何使用此信息的详细信息,请参阅本节后面的“注释”中的“ParameterValuePtr 参数”。 有关参数的按列绑定的详细信息,请参阅 “绑定参数数组”。

行形参数绑定

在行绑定中,应用程序定义一个结构,该结构包含要绑定的每个参数的参数和长度/指示器缓冲区。

若要使用按行绑定,应用程序将执行以下步骤:

  1. 定义一个结构,用于保存一组参数(包括参数和长度/指示器缓冲区),并分配这些结构的数组。

    注意

    如果使用行绑定时应用程序直接写入描述符,则可以将单独的字段用于长度和指示器数据。

  2. 将 SQL_ATTR_PARAM_BIND_TYPE 语句属性设置为包含单个参数集的结构的大小,或将参数绑定到的缓冲区实例的大小。 长度必须包含所有绑定参数的空间以及结构或缓冲区的任何填充,以确保当绑定参数的地址随指定长度递增时,结果将指向下一行中相同参数的开头。 在 ANSI C 中使用 sizeof 运算符时,可以保证此行为。

  3. 为每个要绑定的参数调用 SQLBindParameter ::

    • ValueType 是要绑定到列的参数缓冲区成员的类型。

    • ParameterType 是参数的 SQL 类型。

    • ParameterValuePtr 是第一个数组元素中参数缓冲区成员的地址。

    • BufferLength 是参数缓冲区成员的大小。

    • StrLen_or_IndPtr 是要绑定的长度/指示器成员的地址。

有关如何使用此信息的详细信息,请参阅本节后面的“ParameterValuePtr 参数”。 有关参数的按行绑定的详细信息,请参阅 参数的绑定数组。

错误信息

如果驱动程序未将参数数组实现为批处理(SQL_PARAM_ARRAY_ROW_COUNTS选项等于 SQL_PARC_NO_BATCH),则会像执行一个语句一样处理错误情况。 如果驱动程序将参数数组作为批处理实现,应用程序可以使用 IPD 的SQL_DESC_ARRAY_STATUS_PTR标头字段来确定 SQL 语句的参数或导致 SQLExecDirect 或 SQLExecute 返回错误的数组中的哪个参数。 此字段包含每个参数值行的状态信息。 如果该字段指示发生了错误,诊断数据结构中的字段将指示失败的参数的行和参数编号。 数组中的元素数将由 APD 中的SQL_DESC_ARRAY_SIZE标头字段定义,该字段可由 SQL_ATTR_PARAMSET_SIZE 语句属性设置。

注意

APD 中的SQL_DESC_ARRAY_STATUS_PTR标头字段用于忽略参数。 有关忽略参数的详细信息,请参阅下一部分“忽略一组参数”。

当 SQLExecuteSQLExecDirect 返回SQL_ERROR时,IPD 中SQL_DESC_ARRAY_STATUS_PTR字段指向的数组中的元素将包含SQL_PARAM_ERROR、SQL_PARAM_SUCCESS、SQL_PARAM_SUCCESS_WITH_INFO、SQL_PARAM_UNUSED或SQL_PARAM_DIAG_UNAVAILABLE。

对于此数组中的每个元素,诊断数据结构包含一个或多个状态记录。 结构的SQL_DIAG_ROW_NUMBER字段指示导致错误的参数值的行号。 如果可以确定导致错误的参数行中的特定参数,参数编号将在SQL_DIAG_COLUMN_NUMBER字段中输入。

如果未使用参数,则输入SQL_PARAM_UNUSED,因为早期参数中发生错误,该参数强制 SQLExecuteSQLExecDirect 中止。 例如,如果在执行导致 SQLExecute 或 SQLExecDirect 中止的第 40 个参数集时出现 50 个参数和错误,则在参数 41 到 50 的状态数组中输入SQL_PARAM_UNUSED。

当驱动程序将参数数组视为整体单元时,将输入SQL_PARAM_DIAG_UNAVAILABLE,因此它不会生成此单个参数级别的错误信息。

处理单个参数集时出现一些错误,导致处理数组中的后续参数集停止。 其他错误不会影响后续参数的处理。 哪些错误将停止处理,是驱动程序定义的。 如果未停止处理,则处理数组中的所有参数,SQL_SUCCESS_WITH_INFO将因错误返回,并且由SQL_ATTR_PARAMS_PROCESSED_PTR定义的缓冲区设置为处理的参数集总数(由SQL_ATTR_PARAMSET_SIZE语句属性定义),其中包括错误集。

注意

当在处理参数数组时发生错误时,ODBC 行为在 ODBC 3 中有所不同。x 与 ODBC 2 中的 x 相比。x. 在 ODBC 2 中。x,函数返回SQL_ERROR并停止处理。 SQLParamOptionspirow 参数指向的缓冲区包含错误行的数目。 在 ODBC 3 中。x,函数返回SQL_SUCCESS_WITH_INFO,处理可能会停止或继续。 如果继续,则由SQL_ATTR_PARAMS_PROCESSED_PTR指定的缓冲区将设置为处理的所有参数的值,包括导致错误的参数的值。 这种行为更改可能会导致现有应用程序出现问题。

SQLExecuteSQLExecDirect 在完成参数数组中所有参数集的处理之前返回(例如返回SQL_ERROR或SQL_NEED_DATA时),状态数组将包含已处理这些参数的状态。 IPD 中SQL_DESC_ROWS_PROCESSED_PTR字段指向的位置包含参数数组中导致SQL_ERROR或SQL_NEED_DATA错误代码的行号。 将参数数组发送到 SELECT 语句时,状态数组值的可用性是驱动程序定义的;在执行语句或提取结果集后,它们可能可用。

忽略一组参数

APD 的SQL_DESC_ARRAY_STATUS_PTR字段(由 SQL_ATTR_PARAM_STATUS_PTR 语句属性设置)可用于指示应忽略 SQL 语句中的一组绑定参数。 若要指示驱动程序在执行过程中忽略一组或多组参数,应用程序应执行以下步骤:

  1. 调用 SQLSetDescField 将 APD 的SQL_DESC_ARRAY_STATUS_PTR标头字段设置为指向 SQLUSMALLINT 值的数组以包含状态信息。 还可以通过调用具有SQL_ATTR_PARAM_OPERATION_PTR属性的 SQLSetStmtAttr 来设置此字段,这样应用程序就可以设置字段,而无需获取描述符句柄。

  2. 将 APD SQL_DESC_ARRAY_STATUS_PTR 字段定义的数组的每个元素设置为以下两个值之一:

    • SQL_PARAM_IGNORE,指示行已从语句执行中排除。

    • SQL_PARAM_PROCEED,指示行包含在语句执行中。

  3. 调用 SQLExecDirectSQLExecute 以执行准备的语句。

以下规则适用于 APD SQL_DESC_ARRAY_STATUS_PTR 字段定义的数组:

  • 默认情况下,指针设置为 null。

  • 如果指针为 null,则使用所有参数集,就像所有元素都设置为SQL_ROW_PROCEED一样。

  • 将元素设置为SQL_PARAM_PROCEED不能保证操作将使用该特定参数集。

  • 头文件中SQL_PARAM_PROCEED定义为 0。

应用程序可以将 APD 中的SQL_DESC_ARRAY_STATUS_PTR字段设置为指向 IRD 中SQL_DESC_ARRAY_STATUS_PTR字段所指向的同一数组。 将参数绑定到行数据时,这非常有用。 然后,可以根据行数据的状态忽略参数。 除了SQL_PARAM_IGNORE,以下代码还会导致 SQL 语句中的参数被忽略:SQL_ROW_DELETED、SQL_ROW_UPDATED和SQL_ROW_ERROR。 除了SQL_PARAM_PROCEED,以下代码还会导致 SQL 语句继续:SQL_ROW_SUCCESS、SQL_ROW_SUCCESS_WITH_INFO和SQL_ROW_ADDED。

重新绑定参数

应用程序可以执行两个操作之一来更改绑定:

  • 调用 SQLBindParameter 为已绑定的列指定新绑定。 驱动程序使用新绑定覆盖旧绑定。

  • 指定要添加到由对 SQLBindParameter 的绑定调用指定的缓冲区地址的偏移量。 有关详细信息,请参阅下一部分“使用 Offsets 重新绑定”。

使用偏移量重新绑定

如果应用程序具有可以包含许多参数的缓冲区区域设置,但对 SQLExecDirectSQLExecute 的调用仅使用几个参数,则重新绑定参数尤其有用。 缓冲区区域中的剩余空间可以通过按偏移量修改现有绑定来用于下一组参数。

APD 中的SQL_DESC_BIND_OFFSET_PTR标头字段指向绑定偏移量。 如果字段为非 null,驱动程序将取消引用指针;如果SQL_DESC_DATA_PTR、SQL_DESC_INDICATOR_PTR和SQL_DESC_OCTET_LENGTH_PTR字段中没有任何值是空指针,请在执行时将取消引用的值添加到描述符记录中的这些字段。 执行 SQL 语句时,将使用新的指针值。 重新绑定后,偏移量仍有效。 由于SQL_DESC_BIND_OFFSET_PTR是指向偏移量的指针,而不是偏移量本身,因此应用程序可以直接更改偏移量,而无需调用 SQLSetDescFieldSQLSetDescRec 来更改描述符字段。 默认情况下,指针设置为 null。 可以通过调用 SQLSetDescField 或调用具有 fAttribute 的 SQL_ATTR_PARAM_BIND_OFFSET_PTR 的 SQLSetStmtAttr 来设置 ARD 的SQL_DESC_BIND_OFFSET_PTR字段。

绑定偏移量始终直接添加到SQL_DESC_DATA_PTR、SQL_DESC_INDICATOR_PTR和SQL_DESC_OCTET_LENGTH_PTR字段中的值。 如果偏移量更改为其他值,新值仍将直接添加到每个描述符字段中的值。 新偏移量不会添加到字段值和任何早期偏移量的总和中。

描述符

参数的绑定方式由 APD 和 IPD 的字段确定。 SQLBindParameter 中的参数用于设置这些描述符字段。 也可以由 SQLSetDescField 函数设置字段,尽管 SQLBindParameter 的使用效率更高,因为应用程序不必获取调用 SQLBindParameter 的描述符句柄。

注意

为一个语句调用 SQLBindParameter 可能会影响其他语句。 当显式分配与该语句关联的 ARD 并且也与其他语句关联时,将发生这种情况。 由于 SQLBindParameter 修改了 APD 的字段,因此修改适用于与此描述符关联的所有语句。 如果这不是必需的行为,应用程序应在调用 SQLBindParameter 之前将此描述符与其他语句取消关联。

从概念上讲, SQLBindParameter 按顺序执行以下步骤:

  1. 调用 SQLGetStmtAttr 以获取 APD 句柄。

  2. 调用 SQLGetDescField 以获取 APD 的SQL_DESC_COUNT字段,如果 ColumnNumber 参数的值超过SQL_DESC_COUNT的值,则调用 SQLSetDescField 将SQL_DESC_COUNT的值增加到 ColumnNumber

  3. 多次调用 SQLSetDescField 以将值分配给 APD 的以下字段:

    • 将SQL_DESC_TYPE和SQL_DESC_CONCISE_TYPE设置为 ValueType 的值,但如果 ValueType 是日期/时间或间隔子类型的简明标识符之一,则分别将SQL_DESC_TYPE设置为SQL_DATETIME或SQL_INTERVAL,将SQL_DESC_CONCISE_TYPE设置为简洁标识符,并将SQL_DESC_DATETIME_INTERVAL_CODE设置为相应的日期/时间或间隔子代码。

    • 将SQL_DESC_OCTET_LENGTH字段设置为 BufferLength 的值

    • 将SQL_DESC_DATA_PTR字段设置为 ParameterValue 的值

    • 将SQL_DESC_OCTET_LENGTH_PTR字段设置为StrLen_or_Ind的值

    • 将SQL_DESC_INDICATOR_PTR字段也设置为StrLen_or_Ind的值

    StrLen_or_Ind参数指定参数值的指示器信息和长度。

  4. 调用 SQLGetStmtAttr 以获取 IPD 句柄。

  5. 调用 SQLGetDescField 以获取 IPD 的SQL_DESC_COUNT字段,如果 ColumnNumber 参数的值超过 SQL_DESC_COUNT 的值,则调用 SQLSetDescField 将SQL_DESC_COUNT的值增加到 ColumnNumber

  6. 多次调用 SQLSetDescField 以将值分配给 IPD 的以下字段:

    • 将SQL_DESC_TYPE和SQL_DESC_CONCISE_TYPE设置为 ParameterType 的值,不同之处在于,如果 ParameterType 是日期/时间或间隔子类型的简明标识符之一,则分别将SQL_DESC_TYPE设置为SQL_DATETIME或SQL_INTERVAL,将SQL_DESC_CONCISE_TYPE设置为简洁标识符,并将SQL_DESC_DATETIME_INTERVAL_CODE设置为相应的日期/时间或间隔子代码。

    • 根据 ParameterType 设置一个或多个SQL_DESC_LENGTH、SQL_DESC_PRECISION和SQL_DESC_DATETIME_INTERVAL_PRECISION。

    • 将SQL_DESC_SCALE设置为 DecimalDigits 的值

如果对 SQLBindParameter 的调用失败,则会未定义在 APD 中设置的描述符字段的内容,并且 APD 的SQL_DESC_COUNT字段保持不变。 此外,IPD 中相应记录的SQL_DESC_LENGTH、SQL_DESC_PRECISION、SQL_DESC_SCALE和SQL_DESC_TYPE字段未定义,IPD 的SQL_DESC_COUNT字段保持不变。

调用与 SQLSetParam 的转换

当 ODBC 1.0 应用程序在 ODBC 3 中调用 SQLSetParam 时。x 驱动程序,ODBC 3。x 驱动程序管理器映射调用,如下表所示。

ODBC 1.0 应用程序调用 调用 ODBC 3。x 驱动程序
SQLSetParam(StatementHandle、ParameterNumber、ValueType、ParameterType、LengthPrecision、ParameterScale、ParameterValuePtr、StrLen_or_IndPtr): SQLBindParameter(StatementHandle、ParameterNumber、SQL_PARAM_INPUT_OUTPUT、ValueType、ParameterType、 ColumnSizeDecimalDigits、ParameterValuePtr、SQL_SETPARAM_VALUE_MAX、StrLen_or_IndPtr):

示例

A. 使用 SQLBindParameter 函数

在以下示例中,应用程序准备一个 SQL 语句以将数据插入 ORDERS 表中。 对于语句中的每个参数,应用程序调用 SQLBindParameter 来指定参数的 ODBC C 数据类型和 SQL 数据类型,并将缓冲区绑定到每个参数。 对于每一行数据,应用程序将数据值分配给每个参数,并调用 SQLExecute 来执行语句。

下面的示例假定计算机上有一个名为 Northwind 的 ODBC 数据源,该数据源与 Northwind 数据库相关联。

有关更多代码示例,请参阅 SQLBulkOperations 函数SQLProcedures 函数SQLPutData 函数和 SQLSetPos 函数

// SQLBindParameter_Function.cpp  
// compile with: ODBC32.lib  
#include <windows.h>  
#include <sqltypes.h>  
#include <sqlext.h>  
  
#define EMPLOYEE_ID_LEN 10  
  
SQLHENV henv = NULL;  
SQLHDBC hdbc = NULL;  
SQLRETURN retcode;  
SQLHSTMT hstmt = NULL;  
SQLSMALLINT sCustID;  
  
SQLCHAR szEmployeeID[EMPLOYEE_ID_LEN];  
SQL_DATE_STRUCT dsOrderDate;  
SQLINTEGER cbCustID = 0, cbOrderDate = 0, cbEmployeeID = SQL_NTS;  
  
int main() {  
   retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);  
   retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);   
  
   retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);   
   retcode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);  
  
   retcode = SQLConnect(hdbc, (SQLCHAR*) "Northwind", SQL_NTS, (SQLCHAR*) NULL, 0, NULL, 0);  
   retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);  
  
   retcode = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, EMPLOYEE_ID_LEN, 0, szEmployeeID, 0, &cbEmployeeID);  
   retcode = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &sCustID, 0, &cbCustID);  
   retcode = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_TYPE_DATE, SQL_TIMESTAMP, sizeof(dsOrderDate), 0, &dsOrderDate, 0, &cbOrderDate);  
  
   retcode = SQLPrepare(hstmt, (SQLCHAR*)"INSERT INTO Orders(CustomerID, EmployeeID, OrderDate) VALUES (?, ?, ?)", SQL_NTS);  
  
   strcpy_s((char*)szEmployeeID, _countof(szEmployeeID), "BERGS");  
   sCustID = 5;  
   dsOrderDate.year = 2006;  
   dsOrderDate.month = 3;  
   dsOrderDate.day = 17;  
  
   retcode = SQLExecute(hstmt);  
}  

B. 使用命名参数执行存储过程

在以下示例中,应用程序使用命名参数执行 SQL Server 存储过程。

// SQLBindParameter_Function_2.cpp  
// compile with: ODBC32.lib  
// sample assumes the following stored procedure:  
// use northwind  
// DROP PROCEDURE SQLBindParameter  
// GO  
//   
// CREATE PROCEDURE SQLBindParameter @quote int  
// AS  
// delete from orders where OrderID >= @quote  
// GO  
#include <windows.h>  
#include <sqltypes.h>  
#include <sqlext.h>  
  
SQLHDESC hIpd = NULL;  
SQLHENV henv = NULL;  
SQLHDBC hdbc = NULL;  
SQLRETURN retcode;  
SQLHSTMT hstmt = NULL;  
SQLCHAR szQuote[50] = "100084";  
SQLINTEGER cbValue = SQL_NTS;  
  
int main() {  
   retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);  
   retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);   
  
   retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);   
   retcode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);  
  
   retcode = SQLConnect(hdbc, (SQLCHAR*) "Northwind", SQL_NTS, (SQLCHAR*) NULL, 0, NULL, 0);  
   retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);  
  
   retcode = SQLPrepare(hstmt, (SQLCHAR*)"{call SQLBindParameter(?)}", SQL_NTS);  
   retcode = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 50, 0, szQuote, 0, &cbValue);  
   retcode = SQLGetStmtAttr(hstmt, SQL_ATTR_IMP_PARAM_DESC, &hIpd, 0, 0);  
   retcode = SQLSetDescField(hIpd, 1, SQL_DESC_NAME, "@quote", SQL_NTS);  
  
   retcode = SQLExecute(hstmt);  
}  
有关以下内容的信息 请参阅
返回有关语句中参数的信息 SQLDescribeParam 函数
执行 SQL 语句 SQLExecDirect 函数
执行准备的 SQL 语句 SQLExecute 函数
释放语句上的参数缓冲区 SQLFreeStmt 函数
返回语句参数数 SQLNumParams 函数
返回要为其发送数据的下一个参数 SQLParamData 函数
指定多个参数值 SQLParamOptions 函数
在执行时发送参数数据 SQLPutData 函数

另请参阅

ODBC API 参考
ODBC 头文件
使用 SQLGetData 检索输出参数