You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 22:13:17