Я борюсь с проблемой, касающейся запуска оператора SQL для базы данных Oracle через C ++, используя occi. Мой код выглядит следующим образом:
#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;
}
Отображаемая ошибка:
Необработанное исключение в 0x1048ad7a (msvcp100d.dll) в MyDatabaseApp.exe: 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;
Работает нормально, без ошибок. Я думаю, это потому, что получение целого числа просто возвращает примитив, но когда объект возвращается, он взрывается (я думаю о деструкторе, но я не уверен, почему …)
Я играл с этим часами сегодня, и я довольно застрял.
Некоторая информация о моей системе:
Свойства моего проекта следующие:
Надеюсь, я не путал слишком много информации … Любая помощь или понимание было бы здорово, заранее спасибо!
РЕДАКТИРОВАТЬ Если я переписываю свой цикл, сохраняя значение в локальной переменной, в конце цикла выдается ошибка:
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) конечного пользователя и поставщика.
Проверьте этот.
Связанные проблемы:
Сначала попробуйте использовать правильные lib и dll. Если скомпилировано в режиме отладки, то все библиотеки и библиотеки должны быть отлажены. Используйте вид модулей VC ++, чтобы убедиться, что загружена правильная DLL.
Мне повезло с моим приложением, чтобы все библиотеки были скомпилированы для MSVC2010. Поэтому я просто проверяю библиотеки DLL режима отладки и выпуска и получаю работающее приложение.
Я вернулся к этой проблеме около месяца назад и обнаружил, что библиотека MSVC2010 occi была создана для Oracle 11g. У нас работает Oracle 10g, поэтому мне пришлось использовать библиотеку MSVC2005. Поэтому я установил устаревшую IDE и загрузил библиотеку Debug, и она заработала (хотя по какой-то причине версия выпуска не работала).
РЕДАКТИРОВАТЬ
Для тех, у кого возникла та же проблема, что и у меня, если переход с IDV с MSVC2010 на MSVC2005 с соответствующими библиотеками не работает, вы можете попробовать обновить клиент Oracle с 10g до 11g и использовать библиотеку MSVC2010, как предлагает harvyS. Оглядываясь назад, это, вероятно, было бы лучшим решением.