Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 12.0.1 » SQL Anywhere 服务器 - 编程 » ODBC 支持 » ODBC 应用程序中的结果集

 

数据检索

若要从数据库检索行,可使用 SQLExecute 或 SQLExecDirect 执行 SELECT 语句。这将为该语句打开一个游标。

然后,使用 SQLFetch 或 SQLFetchScroll 通过游标读取行。这些函数从结果集读取下一个数据行集,并为所有绑定列返回数据。使用 SQLFetchScroll,可在绝对位置或相对位置,或者通过书签来指定行集。SQLFetchScroll 替换 ODBC 2.0 规范中旧的 SQLExtendedFetch。

应用程序使用 SQLFreeHandle 释放语句后,它将关闭游标。

若要从游标读取值,您的应用程序可以使用 SQLBindCol 或 SQLGetData。如果使用 SQLBindCol,则会在每次读取时自动检索值。如果使用 SQLGetData,您必须在每次读取后为每一列调用它。

SQLGetData 用来逐段读取 LONG VARCHAR 或 LONG BINARY 之类的列的值。另一种方法,还可以将 SQL_ATTR_MAX_LENGTH 语句属性设置为一个很大的值,使之能够包含列的整个值。SQL_ATTR_MAX_LENGTH 的缺省值为 256 KB。

SQL Anywhere ODBC 驱动程序实现 SQL_ATTR_MAX_LENGTH 的方式与 ODBC 规范的目标方式不同。SQL_ATTR_MAX_LENGTH 的用意是作为截断较大读取的机制来使用。它可以 "预览" 模式实现,其中仅显示数据的第一部分。例如:不是从服务器向客户端应用程序传输 4 MB blob,而是只传输前 500 字节(通过设置 SQL_ATTR_MAX_LENGTH 为 500)。SQL Anywhere ODBC 驱动程序不支持此实现。

以下代码段在查询时打开游标,并通过游标检索数据。为了使示例更容易读,这里省略了错误检查。该代码段节选自一个完整示例,可在 %SQLANYSAMP12%\SQLAnywhere\ODBCSelect\odbcselect.cpp 下找到。



SQLINTEGER cbDeptID = 0, cbDeptName = SQL_NTS, cbManagerID = 0;
SQLCHAR deptName[ DEPT_NAME_LEN + 1 ];
SQLSMALLINT deptID, managerID;
SQLHENV  env;
SQLHDBC  dbc;
SQLHSTMT stmt;
SQLRETURN retcode; 
SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env );
SQLSetEnvAttr( env, 
            SQL_ATTR_ODBC_VERSION, 
            (void*)SQL_OV_ODBC3, 0);
SQLAllocHandle( SQL_HANDLE_DBC, env, &dbc );
SQLConnect( dbc,
            (SQLCHAR*) "SQL Anywhere 12 Demo", SQL_NTS,
            (SQLCHAR*) "DBA", SQL_NTS,
            (SQLCHAR*) "sql", SQL_NTS );
SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );
SQLBindCol( stmt, 1, 
            SQL_C_SSHORT, &deptID, 0, &cbDeptID);
SQLBindCol( stmt, 2, 
            SQL_C_CHAR, deptName, 
            sizeof(deptName), &cbDeptName);
SQLBindCol( stmt, 3, 
            SQL_C_SSHORT, &managerID, 0, &cbManagerID); 
SQLExecDirect( stmt, (SQLCHAR * )
"SELECT DepartmentID, DepartmentName, DepartmentHeadID FROM Departments "
               "ORDER BY DepartmentID", SQL_NTS );
while( ( retcode = SQLFetch( stmt ) ) != SQL_NO_DATA ){
   printf( "%d %20s %d\n", deptID, deptName, managerID );
}
SQLFreeHandle( SQL_HANDLE_STMT, stmt );
SQLDisconnect( dbc );
SQLFreeHandle( SQL_HANDLE_DBC, dbc );
SQLFreeHandle( SQL_HANDLE_ENV, env );

在游标中可读取的行位置编号受整数的大小制约。您最多可以读取到第 2147483646 行,这个数字比可以在 32 位整数中保存的值小 1。在使用负数(从末尾开始计算行数)时,您最多可以读取到的行数比整数中可保存的最大负值大 1。