1

I am struggling with an issue regarding running a SQL statement to an Oracle database through C++, using occi. My code is as follows:

#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;
}

The error that is shown is:

Unhandled exception at 0x1048ad7a (msvcp100d.dll) in MyDatabaseApp.exe: 0xC0000005: Access violation reading location 0xccccccd0.

My program stops inside 'xstring' at the following line of code:

    #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 */

If I change my query to:

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

and the loop statement to:

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

It works fine with no errors. I think this is because getting an integer simply returns a primitive, but when an object is being returned it is blowing up (I think on a destructor, but I'm not sure why...)

I have been playing around with this for hours today, and I am pretty stuck.

Some information about my system:

  • OS - Windows XP
  • Oracle Version - 10g
  • IDE - Microsoft Visual Studio 2010 Express C++

My project properties are as follows:

  • C/C++ - General - Additional Include Directories = C:\oracle\product\10.2.0\client_1\oci\include;%(AdditionalIncludeDirectories)
  • C/C++ - Code Generation - Multi-threaded Debug DLL (/MDd)
  • Linker - General - Additional Library Directories = C:\oracle\product\10.2.0\client_1\oci\lib\msvc\vc8;%(AdditionalLibraryDirectories)
  • Linked - Input - Additional Dependencies = oraocci10.lib;oraocci10d.lib;%(AdditionalDependencies)

I hope I haven't been confusing with too much info... Any help or insight would be great, Thanks in advance!

EDIT If I rewrite my loop, storing the value in a local variable, the error is thrown at the end of the loop:

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
souldzin
  • 1,428
  • 11
  • 23
  • What if you assign rs->getString(1) to a local string variable to examine it in the debugger? What does that show? – OldProgrammer Feb 14 '13 at 22:54
  • @LeorA That was my first thought. So if I create a local variable and assign its value to 'rs->getString(1)' it's value is "1" (as expected) and it prints out, but I get the same error on the closing "}" of the loop... – souldzin Feb 14 '13 at 22:59
  • Looks like some kind of memory corruption problem. Good luck. – OldProgrammer Feb 14 '13 at 23:45

2 Answers2

2

Usually such kind of problems come from differences in build environments (IDE) of end user and provider.

Check this.

Related problems:

First try to use correct lib and dll. If compiled in debug mode then all libs and dlls must be debug. Use VC++ Modules view to be sure that proper DLL loaded.

I was lucky with my application to have all libs compiled for MSVC2010. So I just check debug and release mode DLLs and got working application.

Community
  • 1
  • 1
harvyS
  • 628
  • 7
  • 9
  • Thank you for the links, about a month ago I revisited this question and what I found was that the MSVC2010 library is used only for oracle 11g. We are running 10g, so I had installed MSVC2005 and loaded the appropriate debug library, and it worked (The release mode library did not work for some reason). – souldzin Jul 02 '13 at 14:50
  • Not necessary to match ORACLE database version and client. Rule is that ORACLE client version must be equal or higher then ORACLE database. Even if your Database version 10g You can use client libraries from OracleXE 11. Remember to switch include directory to ORACLEXE 11 too - other will you get NULL connection pointer. – harvyS Jul 03 '13 at 06:57
  • So I suggest to install last OracleXE 11.2.0.2 http://www.oracle.com/technetwork/products/express-edition/downloads/index.html and after take appropriate OCCI libs from: http://www.oracle.com/technetwork/database/occidownloads-083553.html Install MSVC2010 with last service pack (currently SP1) or express edition http://www.microsoft.com/visualstudio/eng/products/visual-studio-2010-express In this way I solved my fails on std::string heap corruptions and application works in debug and release mode. – harvyS Jul 03 '13 at 06:58
  • Also your application must be distributed with OCCI DLL files that was downloaded. – harvyS Jul 03 '13 at 07:00
  • Ok, I agree that it's better to upgrade Oracle, than downgrade the IDE (what I did). In the future, I will do this. Thanks! – souldzin Jul 03 '13 at 14:29
2

I revisited this issue about a month ago and I found that the MSVC2010 occi library was built for Oracle 11g. We are running Oracle 10g, so I had to use the MSVC2005 library. So I installed the outdated IDE and loaded the Debug library and it worked (for some reason the release version wouldn't work though).

EDIT

For anyone who is having the same problem I was, if downgrading the IDE from MSVC2010 to MSVC2005 with the appropriate libraries doesn't work, you could try upgrading the Oracle client from 10g to 11g and use the MSVC2010 library, as suggested by harvyS. In retrospect this would've probably been the better solution.

souldzin
  • 1,428
  • 11
  • 23