1

我正在努力解决有关使用 occi 通过 C++ 向 Oracle 数据库运行 SQL 语句的问题。我的代码如下:

#include <iostream>
#include "occi.h"

namespace oc = oracle::occi;

int main() {
    std::cout << "Setting up environment...\n";
    oc::Environment * env = oc::Environment::createEnvironment();

    std::cout << "Setting up connection...\n";
    oc::Connection * conn = env->createConnection("user","pass","server");

    std::cout << "Creating statement...\n";
    //Very simply query... 
    oc::Statement * stmt = conn->createStatement("SELECT '1' FROM dual");

    std::cout << "Executing query...\n";
    oc::ResultSet * rs = stmt->executeQuery();

    while(rs->next()) {
            std::cout << rs->getString(1) << std::endl; //Error is thrown at this line, but after printing since I can see '1' on the console.
    }


    stmt->closeResultSet(rs);
    conn->terminateStatement(stmt);
    env->terminateConnection(conn);
    oc::Environment::terminateEnvironment(env);

    return 0;
}

显示的错误是:

MyDatabaseApp.exe 中 0x1048ad7a (msvcp100d.dll) 处的未处理异常:0xC0000005:访问冲突读取位置 0xccccccd0。

我的程序在以下代码行的“xstring”内停止:

    #if _ITERATOR_DEBUG_LEVEL == 0

    ....

    #else /* _ITERATOR_DEBUG_LEVEL == 0 */
    typedef typename _Alloc::template rebind<_Elem>::other _Alty;

    _String_val(_Alty _Al = _Alty())
            : _Alval(_Al)
            {   // construct allocator from _Al
            ....
            }

    ~_String_val()
            {   // destroy the object
            typename _Alloc::template rebind<_Container_proxy>::other
                    _Alproxy(_Alval);  

            this->_Orphan_all(); //<----------------------Code stops here

            _Dest_val(_Alproxy, this->_Myproxy);
            _Alproxy.deallocate(this->_Myproxy, 1);
            this->_Myproxy = 0;
            }
    #endif /* _ITERATOR_DEBUG_LEVEL == 0 */

如果我将查询更改为:

oc::Statement * stmt = conn->createStatement("SELECT 1 FROM dual"); 

和循环语句:

std::cout << rs->getInt(1) << std::endl;

它工作正常,没有错误。我认为这是因为获取整数只是返回一个原语,但是当一个对象被返回时它会爆炸(我认为是析构函数,但我不确定为什么......)

我今天已经玩了几个小时了,我很困惑。

关于我的系统的一些信息:

  • 操作系统 - Windows XP
  • 甲骨文版 - 10g
  • IDE - Microsoft Visual Studio 2010 Express C++

我的项目属性如下:

  • C/C++ - 常规 - 附加包含目录 = C:\oracle\product\10.2.0\client_1\oci\include;%(AdditionalIncludeDirectories)
  • C/C++ - 代码生成 - 多线程调试 DLL (/MDd)
  • 链接器 - 常规 - 附加库目录 = C:\oracle\product\10.2.0\client_1\oci\lib\msvc\vc8;%(AdditionalLibraryDirectories)
  • 链接 - 输入 - 附加依赖项 = oraocci10.lib;oraocci10d.lib;%(AdditionalDependencies)

我希望我没有对太多信息感到困惑......任何帮助或见解都会很棒,在此先感谢!

编辑如果我重写循环,将值存储在局部变量中,则在循环结束时抛出错误:

while(rs->next()) {
    std::string s = rs->getString(1); //s is equal to "1" as expected
    std::cout << s << std::endl; //This is executed successfully
} //Error is thrown here
4

2 回答 2

2

通常此类问题来自最终用户和提供者的构建环境(IDE)的差异。

检查这个

相关问题:

首先尝试使用正确的 lib 和 dll。如果在调试模式下编译,那么所有的库和 dll 都必须是调试的。使用 VC++ Modules 视图确保加载了正确的 DLL。

我很幸运我的应用程序为 MSVC2010 编译了所有库。所以我只是检查调试和发布模式 DLL 并得到工作应用程序。

于 2013-07-02T11:40:23.497 回答
2

大约一个月前我重新审视了这个问题,发现 MSVC2010 occi 库是为 Oracle 11g 构建的。我们正在运行 Oracle 10g,所以我不得不使用 MSVC2005 库。所以我安装了过时的 IDE 并加载了 Debug 库并且它工作了(由于某种原因,发布版本不起作用)。

编辑

对于遇到相同问题的任何人,如果使用适当的库将 IDE 从 MSVC2010 降级到 MSVC2005 不起作用,您可以尝试将 Oracle 客户端从 10g 升级到 11g 并使用 MSVC2010 库,如 harvyS 所建议的那样。回想起来,这可能是更好的解决方案。

于 2013-07-02T14:59:21.927 回答