Table-Valued 参数和列值的绑定和数据传输

表值参数和其他参数一样,必须绑定这些参数,然后才能将其传递给服务器。 应用程序将表值参数与绑定其他参数的方式相同:使用 SQLBindParameter 或对 SQLSetDescField 或 SQLSetDescRec 的等效调用。 表值参数的服务器数据类型SQL_SS_TABLE。 C 类型可以指定为SQL_C_DEFAULT或SQL_C_BINARY。

在 SQL Server 2008 或更高版本中,仅支持输入表值参数。 因此,任何尝试将SQL_DESC_PARAMETER_TYPE设置为非SQL_PARAM_INPUT的值都将返回SQL_ERROR,SQLSTATE = HY105 和消息“参数类型无效”。

可以使用属性SQL_CA_SS_COL_HAS_DEFAULT_VALUE为整个表值参数列分配默认值。 但是,不能使用 SQLBindParameter StrLen_or_IndPtr中的 SQL_DEFAULT_PARAM为单个表值参数列值分配默认值。 在 SQLBindParameter StrLen_or_IndPtr中使用 SQL_DEFAULT_PARAM ,不能将表值参数作为一个整体设置为默认值。 如果未遵循这些规则,SQLExecute 或 SQLExecDirect 将返回SQL_ERROR。 将使用 SQLSTATE=07S01 和消息“参数 p 的默认参数<无效”生成诊断记录,其中 <p> 是查询语句中 TVP 的序>号。

绑定表值参数后,应用程序必须绑定每个表值参数列。 为此,应用程序首先调用 SQLSetStmtAttr,将SQL_SOPT_SS_PARAM_FOCUS设置为表值参数的序号。 然后,应用程序通过调用以下例程绑定表值参数的列:SQLBindParameter、SQLSetDescRec 和 SQLSetDescField。 将SQL_SOPT_SS_PARAM_FOCUS设置为 0 可还原 SQLBindParameter、SQLSetDescRec 和 SQLSetDescField 在常规顶级参数上运行的常规效果。

对于表值参数本身,不会发送或接收实际数据,但会为每个构成列发送和接收数据。 由于表值参数是伪列,因此 SQLBindParameter 的参数用于引用不同于其他数据类型的属性,如下所示:

参数 非表值参数类型的相关属性,包括列 表值参数的相关属性
InputOutputType IPD 中的SQL_DESC_PARAMETER_TYPE。

对于表值参数列,这必须与表值参数本身的设置相同。
IPD 中的SQL_DESC_PARAMETER_TYPE。

这必须SQL_PARAM_INPUT。
ValueType SQL_DESC_TYPE,在 APD 中SQL_DESC_CONCISE_TYPE。 SQL_DESC_TYPE,在 APD 中SQL_DESC_CONCISE_TYPE。

这必须SQL_C_DEFAULT或SQL_C_BINARY。
ParameterType SQL_DESC_TYPE IPD 中的SQL_DESC_CONCISE_TYPE。 SQL_DESC_TYPE IPD 中的SQL_DESC_CONCISE_TYPE。

这必须SQL_SS_TABLE。
ColumnSize IPD 中的SQL_DESC_LENGTH或SQL_DESC_PRECISION。

这取决于 ParameterType 的值。
SQL_DESC_ARRAY_SIZE

当参数焦点设置为表值参数时,也可以使用SQL_ATTR_PARAM_SET_SIZE进行设置。

对于表值参数,这是表值参数列缓冲区中的行数。
DecimalDigits IPD 中的SQL_DESC_PRECISION或SQL_DESC_SCALE。 闲置。 这必须是 0。

如果此参数不是 0,SQLBindParameter 将返回SQL_ERROR,并且将使用 SQLSTATE= HY104 生成诊断记录,消息“精度或小数位数无效”。
ParameterValuePtr APD 中的SQL_DESC_DATA_PTR。 SQL_CA_SS_TYPE_NAME。

对于存储过程调用,这是可选的,如果不需要,则可以指定 NULL。 必须为不是过程调用的 SQL 语句指定它。

此参数还充当应用程序在使用变量行绑定时可用于标识此表值参数的唯一值。 有关详细信息,请参阅本主题后面的“变量 Table-Valued 参数行绑定”部分。

在调用 SQLBindParameter 时指定表值参数类型名称时,必须将其指定为 Unicode 值,即使在生成为 ANSI 应用程序的应用程序中也是如此。 用于参数 StrLen_or_IndPtr 的值应SQL_NTS或名称的字符串长度乘以 sizeof(WCHAR)。
BufferLength 在 APD 中SQL_DESC_OCTET_LENGTH。 表值参数类型名称的长度(以字节为单位)。

如果类型名称为 null 终止,则可以SQL_NTS;如果不需要表值参数类型名称,则为 0。
StrLen_or_IndPtr APD 中的SQL_DESC_OCTET_LENGTH_PTR。 APD 中的SQL_DESC_OCTET_LENGTH_PTR。

对于表值参数,这是行计数而不是数据长度。

表值参数支持两种数据传输模式:固定行绑定和变量行绑定。

修复了参数行绑定 Table-Valued

对于固定行绑定,应用程序为所有可能的输入列值分配足够大的缓冲区(或缓冲区数组)。 应用程序执行以下作:

  1. 使用 SQLBindParameter、SQLSetDescRec 或 SQLSetDescField 调用绑定所有参数。

    1. 将SQL_DESC_ARRAY_SIZE设置为每个表值参数可以传输的最大行数。 这可以在 SQLBindParameter 调用中完成。
  2. 调用 SQLSetStmtAttr 将SQL_SOPT_SS_PARAM_FOCUS设置为每个表值参数的序号。

    1. 对于每个表值参数,请使用 SQLBindParameter、SQLSetDescRec 或 SQLSetDescField 调用绑定表值参数列。

    2. 对于要具有默认值的每个表值参数列,请调用 SQLSetDescField 将SQL_CA_SS_COL_HAS_DEFAULT_VALUE设置为 1。

  3. 调用 SQLSetStmtAttr 将SQL_SOPT_SS_PARAM_FOCUS设置为 0。 必须在调用 SQLExecute 或 SQLExecDirect 之前执行此作。 否则,将返回SQL_ERROR,并使用 SQLSTATE=HY024 生成诊断记录,消息“属性值无效,SQL_SOPT_SS_PARAM_FOCUS(执行时必须为零)。

  4. 将没有行的表值参数StrLen_or_IndPtr或SQL_DESC_OCTET_LENGTH_PTR设置为SQL_DEFAULT_PARAM;如果表值参数具有行,则为下一次调用 SQLExecute 或 SQLExecDirect 传输的行数。 不能将表 值参数StrLen_or_IndPtr或SQL_DESC_OCTET_LENGTH_PTR设置为SQL_NULL_DATA,因为表值参数不可为 null(尽管表值参数构成列可以为 null)。 如果此值设置为无效值,则 SQLExecute 或 SQLExecDirect 将返回SQL_ERROR,并使用 SQLSTATE=HY090 生成诊断记录,消息“参数 p> 的字符串或缓冲区长度无效”,其中 p 是参数<编号。

  5. 调用 SQLExecute 或 SQLExecDirect。

如果 StrLen_or_IndPtr设置为列的 SQL_LEN_DATA_AT_EXEClength) 或SQL_DATA_AT_EXEC,则可以传入输入表值参数列值。 这类似于在使用参数数组时在片段中传递值。 与执行时所有数据参数一样,SQLParamData 不指示驱动程序请求数据的数组的哪一行;应用程序必须处理此问题。 应用程序无法对驱动程序请求值的顺序做出任何假设。

变量 Table-Valued 参数行绑定

对于可变行绑定,行在执行时分批传输,应用程序按需将行传递到驱动程序。 这类似于单个参数值的数据执行。 对于变量行绑定,应用程序执行以下作:

  1. 如上一节的步骤 1 中所述,将参数和表值参数列绑定到“已修复 Table-Valued 参数行绑定”。

  2. 为在执行时要传递给SQL_DATA_AT_EXEC的任何表值参数设置 StrLen_or_IndPtr 或SQL_DESC_OCTET_LENGTH_PTR。 如果两者均未设置,将按照上一部分所述处理参数。

  3. 调用 SQLExecute 或 SQLExecDirect。 如果有任何SQL_PARAM_INPUT或SQL_PARAM_INPUT_OUTPUT参数作为数据执行参数进行处理,则会返回SQL_NEED_DATA。 在这种情况下,应用程序执行以下作:

    • 调用 SQLParamData。 这会返回数据执行参数的 ParameterValuePtr 值和SQL_NEED_DATA的返回代码。 当所有参数数据都传递给驱动程序时,SQLParamData 将返回SQL_SUCCESS、SQL_SUCCESS_WITH_INFO或SQL_ERROR。 对于执行时的数据参数, ParameterValuePtr 与描述符字段SQL_DESC_DATA_PTR相同,可被视为用于唯一标识需要值的参数的标记。 此“令牌”在绑定时从应用程序传递到驱动程序,然后在执行时传回应用程序。
  4. 若要为空表值参数发送表值参数行数据,如果表值参数没有行,则应用程序将调用 StrLen_or_Ind 设置为SQL_DEFAULT_PARAM的 SQLPutData。

    对于非 NULL TVP,应用程序:

    • 将所有表值参数列 Str_Len_or_Ind 设置为适当的值,并为非执行时数据参数的表值参数列填充数据缓冲区。 可以将执行时的数据用于表值参数列,其方式与普通参数可以分块传递到驱动程序的方式类似。

    • 调用 Str_Len_or_Ind 设置为要发送到服务器的行数的 SQLPutData。 超出范围 0 或SQL_DESC_ARRAY_SIZE或SQL_DEFAULT_PARAM的任何值都是错误,并将返回 SQLSTATE HY090,并显示消息“字符串或缓冲区长度无效”。 0 表示已发送所有行,并且表值参数没有更多数据(如此列表中的第二个项目符号项所述)。 SQL_DEFAULT_PARAM只能在驱动程序第一次请求表值参数的数据时使用(如此列表中的第一个项目符号项中所述)。

  5. 发送所有行后,使用 Str_Len_or_Ind 值为 0 的表值参数调用 SQLPutData,然后继续执行上面的步骤 3a。

  6. 再次调用 SQLParamData。 如果表值参数列中存在任何数据执行参数,这些参数将由 SQLParamData 返回的值 ValuePtrPtrPtr 标识。 当所有列值都可用时,SQLParamData 将再次返回表值参数的 ParameterValuePtr 值,应用程序将再次开始。

另请参阅

表值参数 (ODBC)