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

PHP PDO+ODBC插入Pervasive SQL时遇无效游标状态错误求助

解决PHP PDO+ODBC插入Pervasive SQL时的"Invalid cursor state"错误

问题描述

执行PHP PDO结合ODBC向Pervasive SQL插入记录时,持续触发如下错误:

GSS Query failed: SQLSTATE[07005]: Prepared statement not a cursor-specification: 0 [PSQL][ODBC Client Interface]Invalid cursor state. (SQLFetchScroll[0] at /home/abuild/rpmbuild/BUILD/php-7.4.30/ext/pdo_odbc/odbc_stmt.c:562)

开启PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION时触发错误,移除该配置后插入可成功,但无法捕获异常;尝试过closeCursor()和SQL_CUR_USE_ODBC等方案均无效。

核心原因

INSERT属于数据操作语言(DML)语句,执行后不会返回结果集,但代码中在execute()后调用了fetchAll()——这个方法仅适用于SELECT这类会返回结果集的查询。Pervasive ODBC驱动在开启异常模式时,会严格校验游标状态,发现尝试从非查询语句获取结果集时,直接抛出"Invalid cursor state"错误;关闭异常模式时PDO会忽略该错误,但同时也失去了异常捕获能力。

另外注意:原SQL语句中CUSTOMERNO字段重复出现,属于明显笔误,需要修正。

解决方案

1. 移除INSERT后的fetchAll()调用,替换为行计数验证

将获取结果集的逻辑改为用rowCount()获取受影响行数,代码修改如下:

$dsn_gss = 'odbc:Driver={Pervasive ODBC Interface};ServerName=192.168.175.254;dbq=GSS'; 
$dsn_gss_username = '*******'; 
$dsn_gss_password = '*******';

try {
    $dbh_gss = new PDO($dsn_gss, $dsn_gss_username, $dsn_gss_password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
} catch (PDOException $ex) {
    echo $ex->getMessage();
    exit;
}

try {
    // 修正重复字段的SQL语句
    $query_gss = "INSERT INTO ORDER_TEST (ORDER_NO_EXTERNAL, CUSTOMERNO, PARTNUMBER, QTY, PRICE) VALUES (?, ?, ?, ?, ?)";
    $stmt_gss = $dbh_gss->prepare($query_gss);
    // 对应修正后的字段传递参数
    $stmt_gss->execute(array('SAMPLE_ORDER_1', '001000', '0025', 100, 2.3));
    // 获取受影响行数,验证插入结果
    $affectedRows = $stmt_gss->rowCount();
    echo "成功插入 {$affectedRows} 条记录";
} catch(PDOException $ex) {
    print_r($ex->getMessage());
}

2. 额外驱动兼容调整(可选)

如果上述修改后仍有兼容性问题,可尝试在PDO连接时添加游标库配置,强制使用ODBC游标:

$dbh_gss = new PDO($dsn_gss, $dsn_gss_username, $dsn_gss_password, array(
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ODBC_ATTR_USE_CURSOR_LIBRARY => PDO::ODBC_CURSOR_USE_ODBC
));

验证效果

  • 开启PDO::ERRMODE_EXCEPTION后,插入操作可正常执行,无游标状态错误;
  • 若出现字段不存在、约束违反等错误,会正常抛出PDOException并被捕获;
  • 通过rowCount()可直观确认插入是否成功。

内容的提问来源于stack exchange,提问作者scorpio1441

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 22:25:25