SQLFetch()
- Fetch the next row
SQLFetch()
advances the cursor to the
next row of the result set and retrieves any bound columns. Columns
can be bound to either the application storage or LOB locators.
ODBC specifications for SQLFetch()
ODBC specification level | In X/Open CLI CAE specification? | In ISO CLI specification? |
---|---|---|
1.0 | Yes | Yes |
Syntax
SQLRETURN SQLFetch (SQLHSTMT hstmt);
Function arguments
The following table lists the data type, use, and description for each argument in this function.
Data type | Argument | Use | Description |
---|---|---|---|
SQLHSTMT | hstmt | input | Specifies the statement handle from which to fetch data. |
Usage
When you call SQLFetch()
, Db2 ODBC performs the appropriate
data transfer, along with any data conversion that was indicated when
you bound the column. You can call SQLGetData()
to
retrieve the columns individually after the fetch.
SQLFetch()
only after you generate a result
set. Any of the following actions generate a result set: - Executing a query
- Calling
SQLGetTypeInfo()
- Calling a catalog function
To retrieve multiple rows at a time, use SQLExtendedFetch()
.
Call SQLFetch()
to
retrieve results into bound application variables and to advance the
position of the cursor in a result set. You can call SQLFetch()
only
after a result set is generated on the statement handle. Before you
call SQLFetch()
for the first time, the cursor is
positioned before the start of the result set.
The number of
application variables bound with SQLBindCol()
must
not exceed the number of columns in the result set or SQLFetch()
fails.
When
you retrieve all the rows from the result set, or do not need the
remaining rows, call SQLFreeStmt()
or SQLCloseCursor()
to
close the cursor and discard the remaining data and associated resources.
If SQLBindCol()
has
not been called to bind any columns, then SQLFetch()
does
not return data to the application, but just advances the cursor.
In this case, SQLGetData()
can be called to obtain
all of the columns individually. Data in unbound columns is discarded
when SQLFetch()
advances the cursor to the next row.
For fixed-length data types, or small varying-length data types, binding
columns provides better performance than using SQLGetData()
.
Columns can be bound to application storage or you can use LOB locators.
Fetching
into application storage: SQLBindCol()
binds
application storage to the column. You transfer data from the server
to the application when you call SQLFetch()
. The
length of the data that is available to return is also set.
If
LOB values are too large to retrieve in one fetch, retrieve these
values in pieces either by using SQLGetData()
(which
can be used for any column type), or by binding a LOB locator and
using SQLGetSubString()
.
Fetching into
LOB locators: SQLBindCol()
is used to bind LOB
locators to the column. Only the LOB locator (4 bytes) is transferred
from the server to the application at fetch time.
When your
application receives a locator, it can use the locator in SQLGetSubString()
, SQLGetPosition()
, SQLGetLength()
,
or as the value of a parameter marker in another SQL statement. SQLGetSubString()
can
either return another locator, or the data itself. All locators remain
valid until the end of the transaction in which they are created (even
when the cursor moves to another row), or until they are freed using
the FREE LOCATOR statement.
Handling data truncation: If
any bound storage buffers are not large enough to hold the data returned
by SQLFetch()
, the data is truncated. If character
data is truncated, SQL_SUCCESS_WITH_INFO is returned, and an SQLSTATE
is generated indicating truncation. The SQLBindCol()
deferred
output argument pcbValue contains the actual
length, in bytes, of the column data retrieved from the server. The
application should compare the actual output length to the input buffer
length (pcbValue and cbValueMax arguments
from SQLBindCol()
) to determine which character columns
are truncated.
Truncation of numeric data types is reported as a warning if the truncation involves digits to the right of the decimal point. If truncation occurs to the left of the decimal point, an error is returned (see Diagnostics).
Truncation
of graphic data types is treated the same as character data types,
except that the buffer you specify in the rgbValue argument
for SQLBindCol()
. This buffer is filled to the nearest
multiple of two bytes that is less than or equal to the value you
specify in the cbValueMax argument for SQLBindCol()
.
Graphic (DBCS) data transferred between Db2 ODBC
and the application is not nul-terminated if the C buffer type is
SQL_C_CHAR. If the buffer type is SQL_C_DBCHAR, then nul-termination
of graphic data does occur.
To eliminate warnings when data
is truncated, call SQLSetStmtAttr()
with the SQL_ATTR_MAX_LENGTH
attribute set to a maximum length value. Then allocate a buffer for
the rgbValue argument that is the same number
of bytes (plus the nul-terminator) as the value you specified for
SQL_ATTR_MAX_LENGTH. If the column data is larger than the maximum
length that you specified for SQL_ATTR_MAX_LENGTH, SQL_SUCCESS is
returned. When you specify a maximum length, the length you specify,
not the actual length, is returned in the pcbValue argument.
To
retrieve multiple rows at a time, use SQLExtendedFetch()
.
You cannot mix SQLFetch()
calls with SQLExtendedFetch()
calls
on the same statement handle.
Return codes
SQLFetch()
,
it returns one of the following values: - SQL_SUCCESS
- SQL_SUCCESS_WITH_INFO
- SQL_ERROR
- SQL_INVALID_HANDLE
- SQL_NO_DATA_FOUND
SQL_NO_DATA_FOUND is returned if no rows are in the result
set, or previous SQLFetch()
calls have fetched all
the rows from the result set. If all the rows are fetched, the cursor
is positioned after the end of the result set.
Diagnostics
The following table lists each SQLSTATE that this function generates, with a description and explanation for each value.
SQLSTATE | Description | Explanation |
---|---|---|
01004 | Data truncated. | The data that is returned for one or more columns
is truncated. String values or numeric values are truncated on the
right. (SQLFetch() returns SQL_SUCCESS_WITH_INFO
for this SQLSTATE.) |
07002 | Too many columns. | This SQLSTATE is returned for one or more of the
following reasons:
|
07006 | Invalid conversion. | The data value cannot be converted in a meaningful
manner to the data type that the fCType argument
in SQLBindCol() specifies. |
08S01 | Communication link failure. | The communication link between the application and data source fails before the function completes. |
22002 | Invalid output or indicator buffer specified. | The pcbValue argument
in SQLBindCol() specifies a null pointer, and the
value of the corresponding column is null. The function can not report
SQL_NULL_DATA. |
22008 | Invalid datetime format or datetime field overflow. | This SQLSTATE is returned for one or more of the
following reasons:
|
22012 | Division by zero is invalid. | A value from an arithmetic expression is returned that results in division by zero. |
22018 | Error in assignment. | This SQLSTATE is returned for one or more of the
following reasons:
|
24000 | Invalid cursor state. | The previous SQL statement that is executed on the statement handle is not a query. |
54028 | Maximum LOB locator assigned. | The maximum number of concurrent LOB locators has been reached. A new locator can not be assigned. |
58004 | Unexpected system failure. | Unrecoverable system error. |
HY001 | Memory allocation failure. | Db2 ODBC is not able to allocate the required memory to support the execution or the completion of the function. |
HY002 | Invalid column number. | This SQLSTATE is returned for one or more of the
following reasons:
|
HY010 | Function sequence error. | This SQLSTATE is returned for one or more of the
following reasons:
|
HY013 | Unexpected memory handling error. | Db2 ODBC is not able to access the memory that is required to support execution or completion of the function. |
HY019 | Numeric value out of range. | This SQLSTATE is returned for one or more of the
following reasons:
Important: The associated cursor is undefined if this error is detected by Db2 for z/OS®. If the error is detected by Db2 for Linux®, UNIX, and Windows or by other IBM® relational database management systems, the cursor remains open and continues to advance on subsequent fetch calls. |
HYC00 | Driver not capable. | This SQLSTATE is returned for one or more of the
following reasons:
|
Example
The following
example shows an application that uses SQLFetch()
to
retrieve data from bound columns of a result set.
/* ... */
/*******************************************************************
** main
*******************************************************************/
int
main( int argc, char * argv[] )
{
SQLHENV henv;
SQLHDBC hdbc;
SQLHSTMT hstmt;
SQLRETURN rc;
SQLCHAR sqlstmt[] = "SELECT deptname, location from org where
division = 'Eastern'";
struct { SQLINTEGER ind;
SQLCHAR s[15];
} deptname, location;
/* Macro to initialize server, uid and pwd */
INIT_UID_PWD;
/* Allocate an environment handle */
rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
if (rc != SQL_SUCCESS)
return (terminate(henv, rc));
rc = DBconnect(henv, &hdbc);/* allocate a connect handle, and connect */
if (rc != SQL_SUCCESS)
return (terminate(henv, rc));
rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt);
rc = SQLExecDirect(hstmt, sqlstmt, SQL_NTS);
rc = SQLBindCol(hstmt, 1, SQL_C_CHAR, (SQLPOINTER) deptname.s, 15,
&deptname.ind);
rc = SQLBindCol(hstmt, 2, SQL_C_CHAR, (SQLPOINTER) location.s, 15,
&location.ind);
printf("Departments in Eastern division:\n");
printf("DEPTNAME Location\n");
printf("-------------- -------------\n");
while ((rc = SQLFetch(hstmt)) == SQL_SUCCESS) {
printf("%-14.14s %-14.14s \n", deptname.s, location.s);
}
if (rc != SQL_NO_DATA_FOUND)
CHECK_HANDLE (SQL_HANDLE_STMT, hstmt, RETCODE);
rc = SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
rc = SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT);
printf("Disconnecting .....\n");
rc = SQLDisconnect(hdbc);
rc = SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
rc = SQLFreeHandle (SQL_HANDLE_DBC, henv);
if (rc != SQL_SUCCESS)
return (terminate(henv, rc));
} /* end main */
/* ... */