我遇到了一个关于使用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
- Oracle版本-10g
- IDE-Microsoft Visual Studio 2010学习版C++
我的项目属性如下:
- C/C++-常规-其他包含目录=C:\oracle\product\10.2.0\client_1\oci\Include;%(附加IncludeDirectories)
- C/C++-代码生成-多线程调试DLL(/MDd)
- Linker-General-Additional Library Directories=C:\oracle\product\10.2.0\client_1\oci\lib\msvc\vc8;%(其他库目录)
- Linked-Input-Additional Dependencies=oraocci10.lib;oraocci10d.lib;%(附加依赖项)
我希望我没有被太多的信息弄糊涂。。。任何帮助或见解都将是伟大的,提前感谢!
EDIT如果我重写循环,将值存储在本地变量中,则在循环结束时抛出错误:
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
通常这类问题来自于最终用户和提供者的构建环境(IDE)的差异。
检查一下。
相关问题:
- 0x523d14cf(msvcr100d.dll)处出现未处理的异常
- 为什么这个程序崩溃:在DLL之间传递std::string
首先尝试使用正确的lib和dll。如果在调试模式下编译,则必须调试所有库和dll。使用VC++模块视图来确保加载了正确的DLL。
我很幸运,我的应用程序已经为MSVC2010编译了所有的库。所以我只检查了调试和发布模式的DLL,就得到了可以工作的应用程序。
大约一个月前,我再次讨论了这个问题,发现MSVC2010 occi库是为Oracle11g构建的。我们正在运行Oracle10g,所以我不得不使用MSVC2005库。所以我安装了过时的IDE并加载了调试库,它就工作了(但由于某种原因,发布版本不起作用)。
编辑
对于任何有同样问题的人来说,如果使用适当的库将IDE从MSVC2010降级到MSVC2005不起作用,您可以尝试将Oracle客户端从10g升级到11g,并使用MSVC2010库,正如harvyS所建议的那样。回想起来,这可能是更好的解决方案。