oracle - 为什么选择多于 1 行时在 OCI 程序中出现 ORA-03106?仅 10 克,不是 11 克

标签 oracle oracle10g oracle-call-interface

我的 OCI 应用程序在执行 SELECT * FROM mytable 时返回 ORA-03106(“致命的两任务通信协议(protocol)错误”)在哪里 mytable有四列:INTEGER , VARCHAR(1000) , FLOATDATE , 和两行。如果只有 1 行,则调用成功。如果有 BLOB,调用也会成功。表中的列(也被选中)。

各种论坛都表示NLS_LANG - 相关问题可能是原因 - 即,检索数据时客户端上的字符集转换失败,因为(可能)找不到字符集转换文件。请注意,我已经测试了许多可能的设置 NLS_LANG , NLS_CHARACTERSET , ORA_NLS10 , 和其他环境变量。设置其中某些会影响观察到的行为:有时,Oracle 会抛出 ORA-01034: ORACLE not available ORA-27101: shared memory realm does not exist ;在其他时候,客户端应用程序在检索第一行之前崩溃(崩溃发生在 OCIStmtFetch2() 内)。值得注意的是,如果客户端应用程序在首次建立连接时执行以下查询:ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '.,' ,不发生崩溃;相反,ORA-03106: fatal two-task communication protocol error返回错误。

注意:DATE 的存在是可能的。专栏是造成这种情况的原因 - 但事实证明建立可重现的案例非常困难,所以我按原样发布我的问题。

我花了超过 50 个小时试图解决这个问题。任何帮助将不胜感激。

新:重要的附加细节(见下面的代码片段) :问题仅在分段检索数据期间发生 - 我使用两种方法中的哪一种(动态回调函数,或使用获取/设置片段信息函数的循环方法)并不重要。通过调试器并查看我提供给 OCI 以存储 FETCHED 数据的内存中的缓冲区,第一行中的所有 4 个字段总是被正确检索;第二列的初始 FETCH(这是在使用循环方法时返回有关 VARCHAR 列的信息请求的调用)成功填充所有非动态字段,但不包括 VARCHAR 列(即 INTEGER列已正确填充);然后下一个 FETCH 成功填充 VARCHAR 字段,并且应该成功填充剩余的(非动态)列(FLOAT 和 DATE 字段);但是,FLOAT 字段已正确填充,但 DATE 字段已损坏,此外,此 FETCH 调用应返回成功,但它返回 ORA-03106。

以下代码片段,去掉了不相关的错误检查和其他代码,显示了正在发生的事情:

void RetrieveRow(...)
{
    // All necessary environment, statement, describe, and define functions
    // have already been called; non-dynamic buffers have already been allocated
    retcode = OCIStmtFetch2(mystmt, fConnection->myerrhp, 1, OCI_DEFAULT, 0, OCI_DEFAULT);
    while (retcode == OCI_NEED_DATA)
    {
        // ...
        // ... Define the necessary arguments to OCIStmtGetPieceInfo() here ...
        // ...
        OCIStmtGetPieceInfo(mystmt, fConnection->myerrhp, (dvoid**)&define, &type, &inout, &iter, &idx, &piecep)

        // ...
        // ... Iteratively allocate and increase the buffer size for the required dynamic column here...
        // ...
        OCIStmtSetPieceInfo(define, OCI_HTYPE_DEFINE, fConnection->myerrhp, buf, alenp, piecep, indp, rcodep)

        // ... Call OCIStmtFetch2() as part of the dynamic loop to fetch the next piece
        retcode = OCIStmtFetch2(mystmt, fConnection->myerrhp, 1, OCI_DEFAULT, 0, OCI_DEFAULT);
    }
    // retcode is OCI_SUCCESS here when RetrieveRow() is called for the first row,
    // ... and all data in the first row is properly populated in the buffers.
    // But, when RetrieveRow() is called the second time, the above loop is entered,
    // ... the INTEGER, VARCHAR (a dynamic field), and FLOAT fields are correctly populated,
    // ... but the DATE field is corrupt, retcode is OCI_ERROR, and the error is ORA-03106.
    // ... Note that even with a dynamic callback used instead of a loop, the error is the same.
    // ... Note that when piecewise (dynamic) fetching is NOT used,
    // ... all rows are retrieved successfully and there is no error.
}

注意:正如我的标题更改所反射(reflect)的,使用 OCI 和 Oracle 11g 时不会出现此问题。代码完全不变,但包括 OCI 11g 头文件并加载 11g OCI dll,针对 11g Oracle 数据库服务器监听器/实例运行,代码成功,没有此错误。发生错误的只有10g。

如果可以提供一个引用资料,清楚且有信誉地将此识别为版本 10g 中的 OCI/Oracle 错误,我会很满意。 (我确信它是。)但是,我找不到任何确认这是 OCI/Oracle 错误。

最佳答案

正在使用的 Oracle 客户端和服务器的确切版本是什么?
至少有一个已知的 Oracle 错误可能匹配:

Applies to: Oracle Server - Enterprise Edition - Version: 10.2.0.1 to 10.2.0.2 - Release: 10.2 to 10.2 Information in this document applies to any platform. Checked for relevance on 21-Jan-2010

Symptoms OCI based application intermittently throws ORA-03106: fatal two-task communication proto error and has error entries in application log.

Important : The error may not bee seen in the alert.log and in the SQL NET trace files

Cause This has been identified as a Bug 4523125

Solution Upgrade the Client and the Server to 10.2.0.3


更一般地说,这似乎是 Oracle Support 的一个问题。

关于oracle - 为什么选择多于 1 行时在 OCI 程序中出现 ORA-03106?仅 10 克,不是 11 克,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9848256/

相关文章:

java - Oracle 中的什么数据类型会映射到 Java long?

shell - 为 QT Creator 创建 Oracle OCI 插件

oracle - 重新运行脚本的脚本

oracle - 如何使用 GoldenGate "Kafka"/"Kafka connect"处理程序处理 Oracle 十进制类型?

java - Oracle如果不存在则创建表

sql - 提取oracle中alter语句的ddl

c - OCIlib 库.c : No such file or directory

c - 将参数传递给 Oracle 存储过程

java - 从java禁用触发器

Oracle查询得到ORA-00907 : missing right parenthesis