Informix下执行SQLEndTran后如何保留ODBC游标?
Informix ODBC事务后游标失效问题的解决方法
问题场景
使用unixODBC操作Informix数据库时,先通过SQLFetch读取结果集,中途关闭自动提交执行其他表的修改操作并提交/回滚,之后再次调用SQLFetch时失败,提示游标无效或结果集丢失。已在odbc.ini中设置CURSORBEHAVIOR=1但未生效,该逻辑在Oracle环境下可正常运行。
解决方案
显式配置游标保持属性与游标类型
Informix ODBC驱动默认不会在事务结束后保留游标,即使设置CURSORBEHAVIOR=1,仍需在语句句柄上显式配置游标保持和可滚动属性。在执行SQLPrepare之前,添加以下代码:// 设置事务结束后保持游标打开 SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_HOLD, (SQLPOINTER)SQL_CURSOR_HOLD_ON, 0); // 设置静态游标(或键集驱动游标,按需选择) SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_STATIC, 0);静态游标会将结果集缓存到客户端,事务提交后不会失效;键集驱动游标依赖服务器端键集,同样能在事务后保持有效。
调整事务模式切换逻辑
避免在读取结果集中途切换自动提交模式,建议在执行查询前就将自动提交设置为OFF;若必须中途切换,需确保已提前配置好游标保持属性。验证
odbc.ini配置完整性
除CURSORBEHAVIOR=1外,需补充检查:- 设置
DEFER_PREPARE=NO:避免延迟准备导致游标属性未生效 - 升级Informix ODBC驱动至最新版本:旧版本可能存在
CURSORBEHAVIOR参数的兼容性问题
- 设置
修改后的示例代码
SQLHENV henv = SQL_NULL_HENV; SQLHDBC hdbc = SQL_NULL_HDBC; SQLHSTMT hstmt = SQL_NULL_HSTMT; SQLRETURN retcode; SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0); SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); SQLDriverConnect(hdbc, NULL, (SQLCHAR*)connstr, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE); SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); // 新增:配置游标保持与类型 SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_HOLD, (SQLPOINTER)SQL_CURSOR_HOLD_ON, 0); SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_STATIC, 0); SQLPrepare(hstmt, (SQLCHAR*)"SELECT * from tab1", SQL_NTS); SQLExecute(hstmt); /* fetching ... */ SQLFetch(hstmt); SQLFetch(hstmt); SQLFetch(hstmt); /* autocommit off */ SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0); /* * Do something.. * */ /* commit or rollback */ SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT); /* autocommit on */ SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, 0); /* 现在可正常执行fetch */ SQLFetch(hstmt);
补充说明
Oracle ODBC驱动默认允许事务结束后继续使用游标,但Informix需要显式配置游标保持和类型属性,配合odbc.ini的CURSORBEHAVIOR=1才能实现事务后保留游标的效果。
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

