使用参数的数组

若要使用参数数组,应用程序可以使用 Attribute 参数 SQL_ATTR_PARAMSET_SIZE 来调用 SQLSetStmtAttr,以指定参数集的数量。 它使用 SQL_ATTR_PARAMS_PROCES标准版D_PTR Attribute 参数调用 SQLSetStmtAttr,以指定变量的地址,驱动程序可以在该变量中返回处理的参数集数,包括错误集。 它使用 Attribute 参数 SQL_ATTR_PARAM_STATUS_PTR 调用 SQLSetStmtAttr,以指向一个数组,该数组将返回每行参数值的状态信息。 驱动程序将这些地址存储在它为语句维护的结构中。

注意

在 2.x 中,调用 SQLParamOptions 可以为一个参数指定多个值。 在 ODBC 3.x 中,对 SQLParamOptions 的调用已被对 SQLSetStmtAttr 的调用所取代,从而设置 SQL_ATTR_PARAMSET_SIZE 和 SQL_ATTR_PARAMS_PROCESSED_ARRAY 属性。

在执行语句之前,应用程序会设置每个绑定数组的每个元素的值。 在执行语句时,驱动程序会使用它存储的信息来检索参数值并将其发送到数据源;如果可能,驱动程序应将这些值作为数组发送。 虽然使用参数数组的最佳方式是通过对数据源的一次调用来执行包含数组中所有参数的 SQL 语句,但这种功能目前在 DBMS 中并不广泛可用。 但是,驱动程序可以通过多次执行 SQL 语句来模拟它,每次使用一组参数。

在应用程序使用参数数组之前,必须确保应用程序使用的驱动程序支持它们。 有两种方法可以实现此目的:

  • 只使用已知支持参数数组的驱动程序。 应用程序可以对这些驱动程序的名称进行硬编码,也可以指示用户仅使用这些驱动程序。 自定义应用程序和垂直应用程序通常使用一组有限的驱动程序。

  • 在运行时检查是否支持参数数组。 如果可以将 SQL_ATTR_PARAMSET_SIZE 语句属性设置为大于 1 的值,则驱动程序支持参数数组。 泛型应用程序和垂直应用程序通常会在运行时检查是否支持参数数组。

可以通过使用 SQL_PARAM_ARRAY_ROW_COUNTS 和 SQL_PARAM_ARRAY_SELECTS 选项来调用 SQLGetInfo,从而确定参数化执行中行计数和结果集的可用性。 对于 INSERT、UPDATE 和 DELETE 语句,SQL_PARAM_ARRAY_ROW_COUNTS 选项会指示是使用单独的行计数(每个参数集一个行计数)(SQL_PARC_BATCH) 还是将行计数汇总为一个行计数 (SQL_PARC_NO_BATCH)。 对于 SELECT 语句,SQL_PARAM_ARRAY_SELECTS 选项表示每个参数集是有一个结果集可用 (SQL_PAS_BATCH),还是只有一个结果集可用 (SQL_PAS_NO_BATCH)。 如果驱动程序不允许使用参数数组执行结果集生成语句,则 SQL_PARAM_ARRAY_SELECTS 返回 SQL_PAS_NO_SELECT。 参数数组是否可以与其他类型的语句一起使用取决于数据源,主要是因为这些语句中参数的使用取决于数据源,且不遵循 ODBC SQL 语法。

SQL_ATTR_PARAM_OPERATION_PTR 语句属性所指向的数组可用于忽略参数行。 如果数组的一个元素被设置为 SQL_PARAM_IGNORE,那么与该元素对应的参数集将被排除在 SQLExecute 或 SQLExecDirect 调用之外。 SQL_ATTR_PARAM_OPERATION_PTR 属性所指向的数组由应用程序分配并填充,并由驱动程序读取。 如果将提取的行用作输入参数,则可以在参数操作数组中使用行状态数组的值。

错误处理

如果在执行语句时发生错误,则执行函数将返回错误并将行号变量设置为包含错误的行号。 是执行除错误集以外的所有行,还是执行错误集之前(但不是之后)的所有行,取决于数据源。 由于它处理参数集,因此驱动程序会将 SQL_ATTR_PARAMS_PROCESSED_PTR 语句属性指定的缓冲区设置为当前正在处理的行号。 如果执行了除错误集之外的所有集,则在处理完所有行之后,驱动程序会将此缓冲区设置为 SQL_ATTR_PARAMSET_SIZE。

如果设置了 SQL_ATTR_PARAM_STATUS_PTR 语句属性,那么 SQLExecute 或 SQLExecDirect 将返回参数状态数组,该数组提供每组参数的状态。 参数状态数组由应用程序分配,并由驱动程序填充。 它的元素指示 SQL 语句是成功执行了这行参数,还是在处理这组参数时发生了错误。 如果发生了错误,驱动程序会将参数状态数组中的对应值设置为 SQL_PARAM_ERROR 并返回 SQL_SUCCESS_WITH_INFO。 应用程序可以检查状态数组,以确定处理了哪些行。 使用行号,应用程序通常可以更正错误并恢复处理。

参数状态数组的使用方式由调用 SQLGetInfo 返回的 SQL_PARAM_ARRAY_ROW_COUNTS 和 SQL_PARAM_ARRAY_SELECTS 选项决定。 对于 INSERT、UPDATE 和 DELETE 语句,如果 SQL_PARAM_ARRAY_ROW_COUNTS 返回 SQL_PARC_BATCH,则参数状态数组将填充状态信息,如果返回 SQL_PARC_NO_BATCH,则不填充状态信息。 对于 SELECT 语句,如果 SQL_PARAM_ARRAY_SELECT 返回 SQL_PAS_BATCH,则填充参数状态数组,如果返回 SQL_PAS_NO_BATCH 或 SQL_PAS_NO_SELECT,则不填充参数状态数组。

执行时数据参数

如果长度/指示器数组中的任何值是 SQL_DATA_AT_EXEC 或 SQL_LEN_DATA_AT_EXEC(length) 宏的结果,则这些值的数据将以通常的方式与 SQLPutData 一起发送。 此过程的以下方面值得特别评论,因为它们并不明显:

  • 当驱动程序返回 SQL_NEED_DATA 时,它必须将行号变量的地址设置为需要数据的行。 与单值情况一样,应用程序不能对驱动程序在单个参数集中请求参数值的顺序做出任何假设。 如果在执行执行时数据参数的过程中发生错误,由 SQL_ATTR_PARAMS_PROCESSED_PTR 语句属性指定的缓冲区将被设置为发生错误的行号,由 SQL_ATTR_PARAM_STATUS_PTR 语句属性指定的行状态数组中的行状态将被设置为 SQL_PARAM_ERROR,对 SQLExecute、SQLExecDirect、SQLParamData 或 SQLPutData 的调用将返回 SQL_ERROR。 如果 SQLExecute、SQLExecDirect 或 SQLParamData 返回 SQL_STILL_EXECUTING,则该缓冲区的内容是未定义的。

  • 由于驱动程序不解释 SQLBindParameter 的 ParameterValuePtr 参数中用于执行时数据参数的值,因此如果应用程序提供指向数组的指针,SQLParamData 不会提取此数组的元素并将其返回给应用程序。 而是返回应用程序提供的标量值。 这意味着 SQLParamData 返回的值不足以指定应用程序需要发送数据的参数;应用程序还需要考虑当前行号。

    当参数数组中只有一些元素是执行时数据参数时,应用程序必须在 ParameterValuePtr 中传递包含所有参数元素的数组的地址。 对于非执行时数据参数的参数,通常会对此数组进行解释。 对于执行时数据参数,SQLParamData 提供给应用程序的值(通常可用于标识驱动程序在这种情况下请求的数据)始终是数组的地址。