用户有两种方法通过 CLI 从 DB2 Everyplace 表检索数据:
如果是二进制数据(BLOB)或字符数据(CHAR 或 VARCHAR),列可能会很长。应用程序开发者可能不想分配的缓冲区太大以装入整列,或者可能无法分配这么大的缓冲区。此外,在某些情况下,应用程序只需要列的某些部分。在这些方案中,需要逐块检索数据。
过程
SQLGetData() 功能允许应用程序使用重复的调用来依次获取单个列的值(以多个可管理数据块的形式)。实际上,调用 SQLGetData() 将返回 SQL_SUCCESS_WITH_INFO(带有 SQLSTATE 01004)以指示此列存在更多数据。重复调用 SQLGetData() 以获取余下数据块,直到它返回 SQL_SUCCESS,指示已检索此列的全部数据。
语法
SQLRETURN SQLGetData (
SQLHSTMT StatementHandle, /* hstmt */
SQLUSMALLINT ColumnNumber, /* icol */
SQLSMALLINT TargetType, /* fCType */
SQLPOINTER TargetValuePtr, /* rgbValue */
SQLINTEGER BufferLength, /* cbValueMax */
SQLINTEGER *FAR StrLen_or_IndPtr); /* pcbValue */
这将一次检索 BufferLength 个字节,而 StrLen_or_IndPtr 指示余下的字节数。如果有字节余下,函数的返回值为 SQL_SUCCESS_WITH_INFO(带有 SQLSTATE 01004)。或者,如果返回值为 SQL_SUCCESS,则 StrLen_or_IndPtr 指示 DB2 Everyplace CLI 可在 TargetValuePtr 缓冲区中返回的字节数。如果 C 数据类型(TargetType)为 SQL_C_CHAR 或 SQL_C_BINARY,或者如果 TargetType 为 SQL_C_DEFAULT 且列类型表示二进制或字符串,则可以此方式使用 SQLGetData() 来检索长列。
要使用 SQLGetData() 的这一功能,必须先将语句属性 SQL_ATTR_GETDATA_MODE 设置为 SQL_PIECEMEAL_DATA。此属性的缺省值为 SQL_CHUNK_DATA。这两种方式之间的区别在于:在 SQL_CHUNK_DATA 方式(这是缺省方式)中,当发生截断时,SQLGetData() 的返回值 StrLen_or_IndPtr 指示此列的总字节数,而第二个调用仍然从该列的最开始检索数据。
示例代码片段
sqlrc = SQLSetStmtAttr(hstmt, SQL_ATTR_GETDATA_MODE, (SQLPOINTER) SQL_PIECEMEAL_DATA, 0); SQLCHAR * stmt = (SQLCHAR *) "SELECT blobColumn FROM t1 where c1 = ?"; sqlrc = SQLPrepare( hstmt, stmt, SQL_NTS ) ; sqlrc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, ...); sqlrc = SQLExecute( hstmt ) ; sqlrc = SQLFetch( hstmt ); /* get BUFSIZ bytes at a time, bufInd indicates number of Bytes LEFT */ sqlrc = SQLGetData (hstmt, 1, SQL_C_BINARY, (SQLPOINTER) buffer, BUFSIZ, &bufInd); while( sqlrc == SQL_SUCCESS_WITH_INFO ) { // handle BUFSIZ bytes of blob data in buffer : sqlrc = SQLGetData (hstmt, 1, SQL_C_BINARY, (SQLPOINTER) buffer, BUFSIZ, &bufInd); } if (sqlrc == SQL_SUCCESS) { /* partial buffer on last GetData */ // handle bufInd bytes of blob data in buffer : }