Thinking Different




* ODBC란 간단히 말해서 엄청나게 많은 sql회사 각각의 제품들을 ODBC 연동API 하나로 쉽게 관리하는것??  정도로 해석이 되겠습니다.
 즉, mysql이나 ms access 기타 oracle등 각각 회사제품 sql의 api를 알지 못해도 odbc 연동 api만 익혀두면 다 연결하고 지지고 볶고 할수 있다는것이죠...  odbc 인터페이스 하나로 다 통제를 가능하게 한다!
물론 odbc관리자에서 해당 dbms를 dns잡아주어야 하는 불편함이 있지만 이정도는 걍 누어서 떡먹기죠...


저는 지난 6장에서 사용한 book 테이블을 그대로 odbc를 이용해서 콘솔에 출력하도록 간단 예제만 짜봤습니다. 참고자료는 API정복 2판(김상형)에서 발췌하였습니다.

설정전에 추가적으로 작업을 해야 되는 것이 있습니다. 바로 mysql/ODBC커넥터를 설치하셔야 됩니다.
다운로드는 mysql.com 홈페이지에서 구하실 수 있으며, 필자가 사용한 버전은 5.대 버전입니다.



그럼 odbc를 설정을 해보아야겠지요...


자 위와같이 ODBC관리자를 띄우고 사용자 DNS나 시스템DNS중에 하나를 선택합니다.
사용자는 사용중인 user만 연동, 시스템은 여러사람들이 연동가능 입니다....  파일DNS는 다음시간에 배워보도록 하죠..
저는 시스템 DNS에 mysql_odbc라고 입력하고 연동하였습니다.

시스템DNS에서 추가를 누르면 Mysql ODBC커넥터를 설치하셨으면 아래화면과 같이 mysql부분이 나오게 됩니다.



자 마침을 누르고 아래 화면과 같이 세팅을 해줍니다...  그리고 test를 눌러 확인합시다. 반드시 연결성공이 나와야 됩니다.


자 이제 코드에서 사용할 dns 네임명은 위에 보시는 Data Source Name이 됩니다... 저는 mysql_odbc로 하였습니다. 기본적으로 사용할 데이터베이스도 bbs로 설정하였습니다.


자 이제 모든것이 완료 되었으면 위에 보시는것처럼 odbc관리자에 mysql_odbc가 추가된걸 확인할 수 있습니다. 이 ODBC를 이용해서 기타 다른 sql에서도 다시 임포팅해서 사용할 수도 있습니다.

다음은 소스코드 부분입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// test.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//
 
#include "stdafx.h"
#include "windows.h"
#include "iostream"
 
using namespace std;
 
//////////////////////////
//     SQL ODBC Conn    //
//////////////////////////
#include "sql.h"
#include "sqlext.h"
 
SQLHENV hEnv;
SQLHDBC hDbc;
SQLHSTMT hStmt;
 
//SQLCHAR *ODBC_Name = (SQLCHAR*)"test";
SQLCHAR *ODBC_Name = (SQLCHAR*)"mysql_odbc";
SQLCHAR *ODBC_ID = (SQLCHAR*)"";
SQLCHAR *ODBC_PW = (SQLCHAR*)"";
 
bool DBConnect();
void DBDisConnect();
bool DBExcuteSQL();
//////////////////////////
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    if(DBConnect() == false)
    {
        cout << "접속 에러 종료!" << endl;
        exit(1);
    }
    if(DBExcuteSQL() == false)
    {
        cout << "ExcuteQuery Error!" << endl;
        exit(1);
    }
    DBDisConnect();
 
    return 0;
}
 
// ODBC사용 핸들 할당 및 SQL접속 부분
bool DBConnect()
{
    if(SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv) != SQL_SUCCESS)
        return false;
    if(SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER) != SQL_SUCCESS)
        return false;
    if(SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc) != SQL_SUCCESS)
        return false;
 
    if(SQLConnect(hDbc, ODBC_Name, SQL_NTS, ODBC_ID, SQL_NTS, ODBC_PW, SQL_NTS) != SQL_SUCCESS)
        return false;
 
    if(SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt) != SQL_SUCCESS)
        return false;
 
    return true;
}
 
// 접속 종료 및 핸들 반환
void DBDisConnect()
{
    if(hStmt) SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
    if(hDbc) SQLDisconnect(hDbc);
    if(hDbc) SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
    if(hEnv) SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
}
 
// 해당되는 쿼리 구문 실행 및 출력
bool DBExcuteSQL()
{
    int no, secNo1, secNo2, bookNo;
    SQLCHAR bookName[20], writer[20], company[20];
    SQLINTEGER ino, isecNo1, isecNo2, ibookNo, ibookName, iwriter, icompany;
    TCHAR str[256];
 
    SQLBindCol(hStmt, 1, SQL_INTEGER, &no, sizeof(no), &ino);
    SQLBindCol(hStmt, 2, SQL_INTEGER, &secNo1, sizeof(secNo1), &isecNo1);
    SQLBindCol(hStmt, 3, SQL_INTEGER, &secNo2, sizeof(secNo2), &isecNo2);
    SQLBindCol(hStmt, 4, SQL_INTEGER, &bookNo, sizeof(bookNo), &ibookNo);
    SQLBindCol(hStmt, 5, SQL_CHAR, bookName, sizeof(bookName), &ibookName);
    SQLBindCol(hStmt, 6, SQL_CHAR, writer, sizeof(writer), &iwriter);
    SQLBindCol(hStmt, 7, SQL_CHAR, company, sizeof(company), &icompany);
 
    if(SQLExecDirect(hStmt, (SQLCHAR*)"select no, secNo1, secNo2, bookNo, bookName, writer, company from book", 
SQL_NTS) != SQL_SUCCESS)
    {
        return false;
    }
 
    printf(" NO\tsecNo1\tsecNo2\tbookNo\tbookName\twriter\tcompany\n");
    while(SQLFetch(hStmt) != SQL_NO_DATA)
    {
        printf(" %d\t%d\t%d\t%d\t%s\t%s\t%s\n", no, secNo1, secNo2, bookNo, bookName, writer, company);
    }
 
    if(hStmt) SQLCloseCursor(hStmt);
 
    return true;
}


생각보다 간단하죠...  함수로 나눠 접속, 실행, 종료 3단계로 진행하였습니다...  제일 기초가 되는 소스 부분이기에 테이블에 있는 정보를 출력만 가능하도록 하였습니다.


자 이렇게 해서 출력도 정상적으로 되는것을 확인할 수 있습니다.

mysql를 이용한 class를 제작하고 그 클래스를 이용해서 6장에서 간단한 도서입출력 프로그램을 짰었는데요...  odbc를 이용하게 되면 훨씬 더 간단해지고 심플하게 코딩을 짤 수 있습니다.