home > working > C/C++ > Source, Tip

 


Name  
   조규남 
Subject  
   ODBC를 이용하지 않고 MS SQL에 접속해서 데이터 얻어 오는 방법

 

- 방법 -

 DB-Library for C에 있는 API를 이용해서 만든다.

 

- Library 설치 방법 -

 MS SQL Server가 설치된 폴더(ex. C:\MSSQL7)의 서브 폴더인 DevTools\Include 와
DevTools\Lib에 헤더 파일과 라이브러리가 있다. 필요한 헤더파일과 라이브러리는 다
음과 같다.

sqlfront.h
sqldb.h

ntwdblib.lib

 ntwdblib.lib는 프로젝트에 포함을 시키면 된다. 헤더 파일의 경우 특별한 순서에 의해서
Include 시켜 주어야 한다. 다음과 같이 Include하면 된다.

#ifndef  DBNTWIN32
#define DBNTWIN32
#endif

#include
#include

 DBNTWIN32를 선언해주고 나서 sqlfront.h, sqldb.h 순으로 Include를 해주며, 순서가
바뀌지 않게 주의 해야 한다.

 이렇게 해주면 프로그래밍을 위한 사전 준비는 모두 끝난다.

 

- Coding -

Database를 열고 닫는 것은 다음의 일련된 과정을 격는다.

dbinit() -> dbopen -> dbclose() -> dbexit()

 dbinit()의 경우 리턴값으로 LPSTR을 넘겨주며 DB-Library의 버전 정보가 담겨져 있다.
dbopen을 위해선 여러가지가 필요한다. 코드는 다음과 같다.

 

/*0001*/ PDBPROCESS    dbproc;
/*0002*/ PLOGINREC        login;
/*0003*/ 
/*0004*/ DBLOCKLIB();
/*0005*/ login = dblogin();
/*0006*/
/*0007*/ DBSETLUSER(login,strID);
/*0008*/ DBSETLPWD(login, strPW);
/*0009*/
/*0010*/ if((dbproc = dbopen(login, strServer)) == NULL)
/*0011*/ {
/*0012*/     AfxMessageBox("Login failed!");
/*0013*/     dbfreelogin(login);
/*0014*/     return bRtn;
/*0015*/ }
/*0016*/
/*0017*/ dbfreelogin(login);
/*0018*/ DBUNLOCKLIB();

 1, 2번째 줄에 있는 PDBPROCESS와 PLOGINREC는 sqlfront.h에 정의 되어 있는 구조체로써
PDBPROCESS는 Application과 SQL 서버의 통신을 담당하게 된다. 여러개의 PDBPROCESS
를 만들게 되면 한꺼 번에 여러가지 작업을 할 수 있다. PLOGINREC는 dbopen을 하기 위해서
필요한 로긴 정보를 저장하는 역할을 한다. dblogin()을 통해서 생성되며, dbfreelogin()을 통
해서 메모리에서 해제 할 수 있다. 메모리를 해제 하지 않은 상황에서는 또 다른 dbopen()의
인자로 사용될 수 있다.

 4, 18번째 줄에 있는 DBLOCKLIB()과 DBUNLOCKLIB()은 데이타 베이스 Query를 하는 동안
다른 프로시저가 데이타베이스에 접근하지 못하도록 locking을 하는 역할을 한다.

 이렇게 생성된 데이타베이스와의 연결은 dbclose()를 통해서 닫을 수 있다.

dbclose(dbproc);

 데이타베이스가 연결이 되었으면 dbsqlexec를 통해서 SQL Query를 던지고 결과를 받을 수
있다. 코드는 다음과 같다.

/*0001*/ CString    strTemp;
/*0002*/ strTemp.Empty();
/*0003*/ RETCODE rectcode;
/*0004*/
/*0005*/ char        SQL[255];
/*0006*/
/*0007*/ strTemp.Format("SELECT au_id, au_lname FROM [pubs].[dbo].[author] WHERE au_lname = 'Green' ");
/*0008*/ lstrcpy((LPSTR)SQL,(LPSTR)strTemp.operator const char*());
/*0009*/
/*0010*/ DBLOCKLIB();
/*0011*/ dbcmd(m_dbproc, SQL);
/*0012*/ if (dbsqlexec(dbproc) == FAIL)
/*0013*/ {
/*0014*/     AfxMessageBox("SQL query fail");
/*0015*/     dbclose(dbproc);
/*0016*/ }
/*0017*/ 
/*0018*/
char szLastName[41]; /* Author last name for binding */
/*0010*/ char szFirstName[21]; /* Author first name for binding */
/*0020*/
/*0021*/ while(((rectcode = dbresults(dbproc)) != NO_MORE_RESULTS) && rectcode != FAIL)
/*0022*/ {
/*0023*/     dbbind(dbproc,1,NTBSTRINGBIND, 12L, (LPSTR)szId);
/*0024*/     dbbind(dbproc,2,NTBSTRINGBIND, 41L, (LPSTR)szLastName);
/*0025*/
/*0026*/     while(dbnextrow(m_dbproc) != NO_MORE_ROWS)
/*0027*/     {
/*0028*/         strTemp.Format("ID: %s's name is %s", szId, szLastName);
/*0029*/       AfxMessageBox(strTemp);
/*0030*/     }
/*0031*/ }
/*0032*/ DBUNLOCKLIB();

 11번째 줄의 dbcmd()는 사용자가 작성한 SQL Query를 command buffer에 집어 넣는다. 사용자
는 dbcmd()를 이용해서 여러줄의 SQL Query를 작성할 수 있고, 이렇게 저장된 Query는 그 다음
줄에 나오는 dbsqlexec()에 의해서 SQL서버에 전달되고 실행되게 된다. 

 SQL에서 실행이 끝나고 나면 dbresults()를 통해서 Query의 결과가 나왔는지를 알 수 있다. 성공
적인 결과가 나왔다면 dbbind()를 통해서 서버의 column과 변수를 바인딩시켜주고 dbnextrow()를
통해서 결과를 레코드 단위로 검색할 수 있다.

 Select이외에 구문들 Insert, Update등을 실행한 후에도

 while(((rectcode = dbresults(dbproc)) != NO_MORE_RESULTS) && rectcode != FAIL)

를 호출해야만 제대로된 결과를 얻을 수 있다.


- 기타 -

더 자세한 도움말은 MSDN의 아래 항목을 참고하기 바란다.

Platform SDK
        Data Services
                Microsoft SQL Server Programer's Toolkit
                        Buliding SQL Server Applications
                                DB Library for C

           


yhrgeeeidq :: bURdINUDjlP 2009/10/23  

Name Memo Password  
        


Prev
   Double Buffering

조규남
Next
   [강좌] How to use C++ in MFC No.3 Templet

조규남


Copyright 1999-2018 Zeroboard / skin by JiYoo / edit by Mystous