Visual C++에서 대부분의 데이터베이스 프로그램을 개발한 경우에는 CRecordset class를 사용하게 된다. 왜냐하면 CRecordset class를 사용하면 테이블의 각 필드를 하나의 변수로 생각하고 프로그램을 하면 되기 때문이다. 그리고, 각각의 레코드를 처리하기가 매우 용이하다.
그러나, 레코드단위의 처리가 필요하지 않는 일종의 batch성 작업이면 CDatabase class로 보다 빠르게 처리할 수 있다. 예를 들어 10000건의 레코드가 존재하는데 그중 어떤 필드가 특정값인 레코드만 모두 삭제하고자 한다면 SQL문으로는 할 줄로 가능한 일인테도 CRecordset class를 사용하면 매우 길고 속도가 느린 프로그램이 된다.
아래의 예를 보면 보다 자세히 할 수 있다.
DELETE FROM MYTABLE WHERE AGE='19'
위와 같은 작업을 하는 프로그램을 ODBC를 이용해서 작성한다고 가정해보자. SQL*PLUS로 접속해서 단 한줄만 입력하면 작업이 완료된다. 그러나, CRecordset class를 이용하면 매우 긴 코드를 작성해야 한다. 하나의 레코드를 가져와서 AGE 필드이 값이 19인지를 확인하고 레코드를 삭제한다. 그리고, 다음 레코드를 가져와서 같은 작업을 하게 된다. 만약 레코드의 개수가 10000개이면 수행시간은 다음과 같다.
(레코드 읽는 메소드 + 비교문장 + 레코드삭제 메소드) * 10000 = ?
최소한 레코드를 읽는 메소드(함수와 같은 의미로 사용)와 레코드를 삭제하는 메소드는 각각 10000번씩 호출되어야 하고 if문을 이용하여 AGE 필드의 값을 비교하는 비교문도 10000번이 실행되어야 한다.
위의 예제의 특징을 살펴보면 프로그램내부에서 사용할 목적으로 레코드를 읽어오는것이 아니라는 점이다. 즉, 레코드의 값이 직접적으로 필요하지 않은 경우에는 보다 간단하고 고속으로 SQL문을 처리할 수 있는 방법이 있다.
Visual C++에서 ODBC를 이용하여 SQL문을 바로 실행할 수 있게 해주는 것이 CDatabase class이다.
CDatabase class는 data source와의 연결, SQL실행, 종료의 순서로 동작한다.
Data source와 연결하기 위해서는 Open메소드를 호출한다. 데이터베이스에
연결하기 위해서는 최소한 DSN,UID,PWD정보를 제공해야 한다. 데이터베이스이
이름과 사용자아이디, 비밀번호만 있으면 데이터베이스에 접속히 가능하다.
SQL*PLUS를 이용하여 오라클에 연결할 때 입력하는 정보와 동일하다.
다만, SQL*PLUS에서는 DSN이 아니라 Oracle Alias를 이용한다는 것만 다르다.
CDatabase::Open
virtual BOOL Open( LPCTSTR lpszDSN, BOOL bExclusive = FALSE, BOOL
bReadOnly = FALSE, LPCTSTR lpszConnect = “ODBC;”, BOOL bUseCursorLib
= TRUE );
throw( CDBException, CMemoryException );
Argument 설명
lpszDSN : DSN의 이름을 나타낸다. ODBC관리자에서 설정한 DSN이다.
NULL이면 사용자에게 DSN을 물어본다.
bExclusive : 지원않함
bReadOnly : 읽기 전용으로 설정한다. 이후의 CRecordset은 이 속성을 상속한다.
lpszConnect : Connect string이다. "ODBC;"로 시작한다. 예를 들어 DSN이 test이고 사용자 아이디가 user, 패스워드가 user인 경우는 다음과 같다.
"ODBC;DSN=test;UID=user;PWD=user"
bUseCursorLib : CRecordset을 바로 사용할 경우는 cursor library를 사용하면 않된다.
예제
CDatabase m_dbEmployee;
try
{
m_dbEmployee.Open( _T( "EMPLOYEE"
), FALSE,
FALSE, _T( "ODBC;UID=WORKER;PWD=WORKER" ));
}
catch(CDBException *e)
{
//예외상황 처리루틴
AfxMessageBox(e->m_strError+e->m_strStateNativeOrigin);
}
catch(CMemoryException *e)
{
//예외상황 처리루틴
AfxMessageBox(e->m_strError+e->m_strStateNativeOrigin);
}
실제로 Open메소드에는 우리가 자주 사용하지 않은 argument가 많이 있다. 따라서, 우리자 자주 사용하게 될 메소드는 Open보다는 OpenEx메소드이다. OpenEx메소드는 Open메소드의 보다 편리한 버젼이라고 생각하면 된다.
CDatabase::OpenEx
virtual BOOL OpenEx( LPCTSTR lpszConnectString, DWORD dwOptions
= 0 );
throw( CDBException, CMemoryException );
Argument 설명
lpszConnectString : ODBC Connect string이다. Open메소드의 lpszConnect와 같은 의미이며 형식도 동일하다.
dwOptions : 기본값은 0이다.(공유,쓰기가능,ODBC Cursor Library DLL로드 않됨)
m_dbEmployee.OpenEx( _T( "DSN=EMPLOYEE;UID=WORKER;PWD=WORKER" ),
CDatabase::openReadOnly |
CDatabase::noOdbcDialog );
이제 데이터베이스와 연결이 됬으니 SQL문을 실행하는 방법을 살펴보자.
프로그래머가 제공해야 되는 것은 SQL문을 나타내는 문자열 변수밖에
없다. 즉, SQL문을 문자열 변수에 지정하고 아래의 ExecuteSQL메소드의 argument로
제공하면 된다.
CDatabase::ExecuteSQL
void ExecuteSQL( LPCSTR lpszSQL );
throw( CDBException );
Argument 설명
lpszSQL : SQL문을 나타내는 문자열이고 CString형도 가능하다.
SQL문을 직접실행할 수 있다.
예제
CString strSQL = "DELETE FROM MYTABLE WHERE AGE='19'";
try
{
m_dbEmployee.ExecuteSQL( strSQL );
}
catch(CDBException *e)
{
//예외상황 처리루틴
AfxMessageBox(e->m_strError+e->m_strStateNativeOrigin);
}
catch(CMemoryException *e)
{
//예외상황 처리루틴
AfxMessageBox(e->m_strError+e->m_strStateNativeOrigin);
}
Data source와의 연결을 해제하기 위해서는 Close 메소드를 호출한다.
이 메소드가 호출되면 데이터베이스와의 연결이 끊긴다. 더이상 데이터베이스를
사용하지 않겠다는 의미이다. 이 CDatabase와 관련된 CRecordset 객체를 먼저
Close해주어야 한다.
객체가 소멸하는 것은 아니기 때문에 다시 Open할 수 있다.
대기중인 AddNew와 Edit는 모두 취소된다.
Transaction은 모두 rollback된다.
CDatabase::Close
virtual void Close( );
예제
m_dbEmployee.Close( );
완성된 소스코드
CDatabase m_dbEmployee;
CString strSQL = "DELETE FROM MYTABLE WHERE AGE='19'";
try
{
//데이터베이스 연결
m_dbEmployee.Open( _T( "EMPLOYEE"
), FALSE,
FALSE, _T( "ODBC;UID=WORKER;PWD=WORKER" ));
//SQL문 수행
m_dbEmployee.ExecuteSQL( strSQL
);
}
catch(CDBException *e)
{
//예외상황 처리루틴
AfxMessageBox(e->m_strError+e->m_strStateNativeOrigin);
}
catch(CMemoryException *e)
{
//예외상황 처리루틴
AfxMessageBox(e->m_strError+e->m_strStateNativeOrigin);
}
//데이터베이스 연결 종료
m_dbEmployee.Close( );
Posted by shiftkey


