Skip to content
ozt88 edited this page May 11, 2015 · 9 revisions

ODBC

ODBC는 윈도우에서 정해진 데이터베이스에 접근하는 표준 규격이다. ODBC는 SQL 표준 인터페이스에 근간을 두고 서로다른 데이터 베이스에 맞는 요청으로 자동 변환하여 사용할 수 있게 만들어 준다. 따라서 서로 다른 데이터 베이스의 API를 몰라도 ODBC 인터페이스에서 정해진 방식만 따라가면 그 데이터 베이스를 사용할 수 있다. 이를 위해 각 DB별로 별도의 모듈 및 드라이버가 필요하다. 대부분의 DBMS들이 ODBC를 지원하기 위한 드라이버를 제공하고 있다.

ODBC에 DB 등록하기

ODBC로 데이터베이스에 접근하기 위해서는, 사용하고자 하는 DBMS를 ODBC관리자에서 추가한 뒤에 사용해야 한다. 자세한 내용은 링크

ODBC 준비하기

DB에 연결하기 위해서 먼저 ODBC에 사용되는 핸들을 생성해야 한다.

SQL_HANDLE_ENV  - ENVIRONMENT 환경 핸들
SQL_HANDLE_DBC  - CONNECTION 연결 핸들
SQL_HANDLE_STMT – STATEMENT 명령문 핸들
SQL_HANDLE_DESC – DESCRIPTOR 표현 핸들
  • ODBC 핸들 할당받기
SQLRETURN SQLAllocHandle( //핸들 할당하는 함수
    SQLSMALLINT HandleType, //핸들의 타입
    SQLHANDLE InputHandle,  //새로 만들어질 핸들의 부모 핸들
    SQLHANDLE* OutputHandlePtr //핸들을 저장할 핸들변수
); 
  • DB 연결 : 생성된 핸들을 가지고 디비에 접속한다.
SQLRETURN SQLDriverConnect(
        SQLHDBC         ConnectionHandle,      // DB 연결 핸들
        SQLHWND         WindowHandle,         // 윈도우 핸들 (사용안함)
        SQLCHAR *       InConnectionString,     // 연결 디비 이름
        SQLSMALLINT     StringLength1,          // 연결 문자열의 길이
        SQLCHAR *       OutConnectionString,    //   ID
        SQLSMALLINT     BufferLength,           //   연결 완료된 문자열의 크기 
        SQLCHAR *       OutConnectionString,    //   PW
        SQLSMALLINT *   StringLength2Ptr,       //   연결 완료된 문자열의 길이         
        SQLUSMALLINT    DriverCompletion       // 연결 옵션
);

DB 명령어 실행하기

  1. 생성된 명령문 핸들에 받을 데이터 형식(속성, 값 저장 변수 등)을 바인딩한다.
  • 명령어 핸들 바인딩
SQLRETURN SQLBindParameter(
      SQLHSTMT        StatementHandle,  //명령문 핸들
      SQLUSMALLINT    ParameterNumber,  //매개변수 마커 번호
      SQLSMALLINT     InputOutputType,  //매개변수 입력 타입
      SQLSMALLINT     ValueType,        //매개변수 C 타입
      SQLSMALLINT     ParameterType,    //매개변수 SQL 타입
      SQLULEN         ColumnSize,       //매개변수의 정밀도
      SQLSMALLINT     DecimalDigits,    //자릿수 표현
      SQLPOINTER      ParameterValuePtr,//매개변수로 넘길(받을) 데이터 포인터
      SQLLEN          BufferLength,     //사용되지 않음
      SQLLEN *        StrLen_or_IndPtr  //데이터의 길이
);
  1. 바인딩한 명령어 핸들로 명령어를 실행하고 값을 받아온다.
  • 리턴 핸들 바인딩
SQLRETURN SQLBindCol(
        SQLHSTMT     StatementHandle,  // SQL 명령문 핸들
        SQLUSMALLINT ColumnNumber,     // 열 값의 순서 (1부터 시작)
        SQLSMALLINT  TargetType,       // 열 값의 데이터형 (C Data Type)
        SQLPOINTER   TargetValuePtr,   // 바인딩될 변수
        SQLINTEGER   BufferLength,     // 바인딩될 변수의 크기       
        SQLLEN *     StrLen_or_Ind     // 열 값의 길이OR상태값을 반환 받을 변수
); 
  • 쿼리 실행
SQLRETURN SQLExecDirect(
        SQLHSTMT        StatementHandle,        // SQL 명령문 핸들
        SQLCHAR *       StatementText,          // 실행될 SQL 문
        SQLINTEGER      TextLength              // 실행될 SQL 문의 길이
); 
  • 쿼리 결과 값 받기
SQLRETURN SQLFetch(
        SQLHSTMT        StatementHandle         // SQL 명령문 핸들
);

연결 종료

  1. 명령문 핸들 종료, 할당 해제
  2. 연결 핸들을 끊고 할당 해제
  3. 다른 핸들 할당 해제
  4. 순서대로 실행 코드
SQLCloseCursor( hStmt );                        // STEP 1
SQLFreeHandle( SQL_HANDLE_STMT, hStmt );        // STEP 2
SQLDisconnect( hDBC );                          // STEP 3
SQLFreeHandle( SQL_HANDLE_DBC, hDBC );          // STEP 4
SQLFreeHandle( SQL_HANDLE_ENV, hENV );

DB와 연동하는 다른 대안들

ADO (ActiveX Data Object)

ADO는 ODBC에 접근하기 위해 마이크로소프트에서 표준으로 제작된 컴포넌트 오브젝트 모델 객체/API들의 집합을 말한다. 프로그래밍 언어와 ODBC사이에 원활한 접근을 위해 만들어진 객체 지향형 인터페이스라고 생각하면 될듯. 사용자는 SQL또는 ODBC 접근 방식을 잘 몰라도 좀 더 간단하게 DB에 요청을 날릴 수 있다.

ADO 객체들은 Connection 객체, Recordset 객체, Command객체로 구성된다.

  • Connection 객체 : DB에 연결하기 위해서 사용되는 것처럼 보이지만, 실상은 여러 요청을 날릴 수도 있다. Insert, Update, Delete, Select가 가능하다.
  • Command 객체 : ADO 중급 수준이상부터 사용된다고 한다. SP사용에 편리한 parameter 속성을 사용할 수 있으며, 명령에 timer를 적용하여 잠시 대기시키는 명령등, 고급 옵션들이 추가된다.
  • Recordset 객체 : 요청한 명령의 결과(record)를 받아서 읽을 수 있도록 도와주는 객체이다. record pointer 개념을 도입하여 간편하게 결과 record들을 읽어 올 수 있다.

ORM (Object-Relation Mapping)

이름 그대로 OOP의 객체와 DB의 relation을 매핑해주는 역할을 한다. DB의 entity들은 테이블(relation)형식으로 구성된다. OOP의 객체들은 데이터 멤버 또는 또다른 멤버 객체를 들고 있는 형식으로 구성된다. OOP에서 DB를 연동할때 이 차이점은 불편하게 다가올 수 있다. ORM은 그 간격을 메꿔주는 Layer역할을 한다. 우리는 ORM을 사용하여 OOP의 룰 아래에서 형식이 다른 DB의 relation을 mapping한 객체를 받아 사용할 수 있다.

매핑하는 방식은 크게 one-to-one/ subset/ superset mapping으로 분류할 수 있다.

  • one-to-one mapping : 테이블의 한 row를 하나의 객체 instance로 매핑시켜준다.
  • subset mapping : 하나의 테이블을 여러개의 class로 분류하여 매핑시켜준다. (ex: Person테이블을 각 속성에 따라 나누어 Employee와 Customer로 나누어 매핑)
  • superset mapping : 여러개의 테이블을 하나의 class로 묶어서 매핑시켜준다. (ex: Person테이블과 PersonInfo 테이블을 합성하여 Person객체로 통합하여 매핑)