2013-02-14 3 views
1

occi를 사용하여 C++를 통해 SQL 문을 Oracle 데이터베이스로 실행하는 것과 관련된 문제로 고민하고 있습니다.간단한 Oracle 쿼리 문자열 표시시 "액세스 위반"오류가 발생했습니다 (VS10 Exp C++)

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

는 IS 표시됩니다 오류 :

처리되지 않은 예외를 0x1048ad7a (msvcp100d.dll)에서 MyDatabaseApp.exe에서 다음과 같이 내 코드는가 0xc0000005 : 위치 0xccccccd0 읽기 액세스 위반.

내 프로그램 코드의 다음 줄에 'xstring'내부 정지 :

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

및 루프 문 :

내가 내 쿼리를 변경하는 경우

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

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

오류없이 정상적으로 작동합니다. 나는 이것이 정수를 얻는 것이 단순히 원시적을 반환하기 때문에 발생한다고 생각하지만 객체가 반환 될 때 (소멸자에 대해 생각한다. 그러나 이유는 확실하지 않다.)

내가 놀아왔다. 오늘 몇 시간 동안 이것으로 주위에, 나는 꽤 붙어있다.

내 시스템에 대한 일부 정보 :

  • OS - 윈도우 XP
  • Oracle 버전 - 10g의
  • IDE - 마이크로 소프트 비주얼 스튜디오 2010 익스프레스 C++

내 프로젝트 속성은 다음과 같습니다 :

  • C/C++ - 일반 - 추가가 디렉토리 = C를 포함 : \ 오라클 \ 10.2.0 \ 제품 \ client_1 \ OCI \ 포함, % (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 
+0

로컬 문자열 변수에 rs-> getString (1)을 할당하여 디버거에서 검사하면 어떨까요? 그게 뭘 보여? – OldProgrammer

+0

@LeorA 저의 첫 번째 생각이었습니다. 그래서 내가 지역 변수를 만들고 'rs-> getString (1)'에 값을 할당하면 값이 "1"(예상대로)이고 출력되지만 인쇄 할 때 같은 오류가 발생합니다. 루프 ... – souldzin

+0

메모리 손상 문제가 발생합니다. 행운을 빕니다. – OldProgrammer

답변

2

약 한 달 전에이 문제를 다시 살펴본 결과 MSVC2010 occi 라이브러리가 Oracle 11g 용으로 빌드되었음을 확인했습니다. 우리는 Oracle 10g를 실행 중이므로 MSVC2005 라이브러리를 사용해야했습니다. 그래서 오래된 IDE를 설치하고 디버그 라이브러리를로드하고 어떤 이유로 릴리스 버전이 작동하지 않을 것입니다.

편집 I이었다 같은 문제가있는 사람, 적절한 라이브러리와 MSVC2005에 MSVC2010에서 IDE를 다운 그레이드하는 것은 작동하지 않을 경우, 당신은 10g에서 11g로 Oracle 클라이언트를 업그레이드 시도 할 수 들어

harvyS가 제안한대로 MSVC2010 라이브러리를 사용하십시오. 되돌아 보면 이것은 아마도 더 나은 해결책이었을 것입니다.

2

일반적으로 같은 종류의 올 (IDE).

체크 this.

관련 문제 :

첫 번째 시도는 올바른 LIB 및 DLL을 사용합니다. 디버그 모드로 컴파일 된 경우 모든 libs 및 dll이 디버그되어야합니다. VC++ 모듈보기를 사용하여 적절한 DLL이로드되었는지 확인하십시오.

내 응용 프로그램과 함께 MSVC2010 용으로 컴파일 된 모든 라이브러리를 갖게되어 매우 기뻤습니다. 그래서 난 그냥 디버그 및 릴리스 모드 DLL을 확인하고 작업 응용 프로그램을 가지고있어.

+0

링크를 이용해 주셔서 감사합니다. 약 한 달 전에이 질문을 다시 살펴 보았습니다. MSVC2010 라이브러리는 오라클 11g에서만 사용되었습니다. MSVC2005를 설치하고 적절한 디버그 라이브러리를로드 했으므로 10g을 실행 중이며 작동했습니다 (릴리스 모드 라이브러리가 어떤 이유로 작동하지 않았습니다). – souldzin

+0

ORACLE 데이터베이스 버전과 클라이언트를 일치시킬 필요는 없습니다. 규칙은 ORACLE 클라이언트 버전이 ORACLE 데이터베이스보다 같거나 높아야한다는 것입니다. 데이터베이스 버전 10g라도 OracleXE 11의 클라이언트 라이브러리를 사용할 수 있습니다. include 디렉토리도 ORACLEXE 11로 전환해야합니다. 다른 경우에는 NULL 연결 포인터를 얻게됩니다. – harvyS

+0

따라서 마지막 OracleXE 11.2.0.2 http://www.oracle.com/technetwork/products/express-edition/downloads/index.html 을 설치 한 후 적합한 OCCI 라이브러리를 다음 위치에서 가져 오십시오. http : // www .oracle.com/technetwork/database/occidownloads-083553.html 마지막 서비스 팩 (현재 SP1) 또는 익스프레스 버전이 설치된 MSVC2010을 설치하십시오. http://www.microsoft.com/visualstudio/eng/products/visual-studio- 2010-express 이렇게하면 std :: string heap 손상 및 응용 프로그램이 디버그 및 릴리스 모드에서 작동합니다. – harvyS