与 SQL 语句中的参数一样,使用 SQLBulkOperations 或 SQLSetPos 更新行时或者使用 SQLBulkOperations 插入行时,可以发送长数据。 数据分部分发送,并多次调用 SQLPutData。 在执行时发送数据的列称为 执行时的数据列。
注释
应用程序实际上可以使用 SQLPutData 在执行时发送任何类型的数据,尽管只能在部分发送字符和二进制数据。 但是,如果数据足够小,无法容纳在单个缓冲区中,则通常没有理由使用 SQLPutData。 绑定缓冲区并让驱动程序从缓冲区中检索数据要容易得多。
由于长数据列通常未绑定,因此应用程序必须在调用 SQLBulkOperations 或 SQLSetPos 之前绑定该列,并在调用 SQLBulkOperations 或 SQLSetPos 后将其取消绑定。 该列必须绑定,因为 SQLBulkOperations 或 SQLSetPos 仅在绑定列上运行,并且必须未绑定,以便 SQLGetData 可用于从列检索数据。
若要在执行时发送数据,应用程序执行以下作:
将 32 位值放在行集缓冲区而不是数据值中。 此值稍后将返回到应用程序,因此应用程序应将其设置为有意义的值,例如列数或包含数据的文件的句柄。
将长度/指示器缓冲区中的值设置为SQL_LEN_DATA_AT_EXEC(length) 宏的结果。 此值指示驱动程序,参数的数据将通过 SQLPutData 发送。 向数据源发送长数据时,将使用 长度 值,该数据源需要知道将发送多少字节长数据,以便它可以预先分配空间。 若要确定数据源是否需要此值,应用程序使用 SQL_NEED_LONG_DATA_LEN 选项调用 SQLGetInfo 。 所有驱动程序都必须支持此宏;如果数据源不需要字节长度,驱动程序可以忽略它。
调用 SQLBulkOperations 或 SQLSetPos。 驱动程序发现长度/指示器缓冲区包含 SQL_LEN_DATA_AT_EXEC(length) 宏的结果,并将SQL_NEED_DATA作为函数的返回值返回。
调用 SQLParamData 以响应SQL_NEED_DATA返回值。 如果需要发送长数据, SQLParamData 将返回SQL_NEED_DATA。 在 ValuePtrPtr 参数指向的缓冲区中,驱动程序返回应用程序放置在行集缓冲区中的唯一值。 如果有多个执行时数据列,则应用程序使用此值来确定向哪个列发送数据。驱动程序不需要以任何特定顺序请求执行时数据列的数据。
调用 SQLPutData 将列数据发送到驱动程序。 如果列数据不适合单个缓冲区,这通常发生在长数据的情况下,应用程序会反复调用 SQLPutData 以分段方式发送数据;数据的重新组合由驱动程序和数据源来处理。 如果应用程序传递以 null 结尾的字符串数据,驱动程序或数据源必须在重新汇编过程中删除 null 终止字符。
再次调用 SQLParamData 以指示它已发送列的所有数据。 如果存在尚未发送数据的任何数据执行列,驱动程序将返回SQL_NEED_DATA和下一个执行时数据列的唯一值;应用程序返回到步骤 5。 如果已为执行时的所有数据列发送数据,则行的数据将发送到数据源。 SQLParamData 然后返回 SQL_SUCCESS 或 SQL_SUCCESS_WITH_INFO,并且可以返回 SQLBulkOperations 或 SQLSetPos 可以返回的任何 SQLSTATE。
在 SQLBulkOperations 或 SQLSetPos 返回SQL_NEED_DATA之后,在为执行时的最后一个数据列完全发送数据之前,该语句处于“需要数据”状态。 在此状态下,应用程序只能调用 SQLPutData、 SQLParamData、 SQLCancel、 SQLGetDiagField 或 SQLGetDiagRec;所有其他函数返回 SQLSTATE HY010 (函数序列错误)。 调用 SQLCancel 会取消语句的执行,并将其返回到其以前的状态。 有关详细信息,请参阅 附录 B:ODBC 状态转换表。