Differences between revisions 1 and 2
| Deletions are marked like this. | Additions are marked like this. |
| Line 17: | Line 17: |
| {{{#!sql | {{{#!sql numbers=off |
| Line 36: | Line 36: |
| {{{#!sql | {{{#!sql numbers=off |
| Line 92: | Line 92: |
| {{{#!cplusplus | {{{#!cplusplus numbers=off |
| Line 101: | Line 101: |
| {{{#!cplusplus | {{{#!cplusplus numbers=off |
| Line 312: | Line 312: |
|
== OLE DB 소비자 특성 == OLE DB Consumer Attributes - The OLE DB consumer attributes inject code, based on the OLE DB Consumer Templates, to create a working OLE DB consumer that performs tasks such as opening tables, executing commands, and accessing data. ||<rowclass="THEAD"> 특성 || 설명 || || db_accessor || Binds columns in a rowset and binds them to the corresponding accessor maps. || || db_column || Binds a specified column to the rowset. || || db_command || Executes an OLE DB command. || || db_param || Associates the specified member variable with an input or output parameter. || || db_source || Creates and encapsulates a connection, through a provider, to a data source. || || db_table || Opens an OLE DB table. || === OLE DB 소비자 특성을 이용한 프로그래밍 === * CUserInfo 테이블 쿼리 클래스 선언 {{{#!cplusplus numbers=off // UserInfo.h : CUserInfo 클래스 선언 // #pragma once [ db_table( L"dbo.UserInfo" ) ] class CUserInfo { public: [ db_column(1) ] LONG m_ID; [ db_column(2) ] TCHAR m_Name[21]; [ db_column(3) ] SHORT m_Age; [ db_column(4) ] TCHAR m_Phone[14]; }; }}} * 프로그래밍 과정 {{{#!cplusplus numbers=on // ATL OLE DB 소비자 템플릿 라이브러리 헤더 파일 #include <atldbcli.h> //------------------------------------------------------------------------------ // STEP 1: COM 초기화 HRESULT hr = CoInitialize( NULL ); if( FAILED( hr ) ) { // ERROR: COM 초기화 실패 // 에러 처리 } //------------------------------------------------------------------------------ // STEP 2: 데이터베이스 연결 CDataConnection dbConn; WCHAR szDbStr[ 256 ]; swprintf( szDbStr, L"Provider=SQLOLEDB.1;Data Source=%s;User ID=%s;Password=%s&;Initial Catalog=%s;", SERVER_STR, // 서버 정보 (주소,포트) UID_STR, // 로그인 정보 (사용자 ID) PWD_STR, // 암호 DATABASE_STR ); // DB 이름 hr = dbConn.Open( szDbStr ); if( FAILED( hr ) ) { // ERROR: 데이터베이스 연결 실패 // 에러 처리 } //------------------------------------------------------------------------------ // STEP 3: 쿼리 실행 CUserInfo tblUserInfo; hr = tblUserInfo.OpenRowset( dbConn.m_session ); if( FAILED( hr ) ) { // ERROR: 쿼리 실행 실패 // 에러 처리 } while( S_OK == tblUserInfo.MoveNext() ) { printf( "ID\t: %d\n", tblUserInfo.m_ID ); printf( "Name\t: %s\n", tblUserInfo.m_Name ); printf( "Age\t: %d\n", tblUserInfo.m_Age ); printf( "Phone\t: %s\n", tblUserInfo.Phone ); } //------------------------------------------------------------------------------ // STEP 4: 쿼리 해제 & 데이터베이스 연결 닫기 tblUserInfo.Close(); dbConn.CloseDataSource(); // STEP 5: COM 해제 CoUninitialize(); }}} |
|
| Line 342: | Line 439: |
| {{{#!cplusplus | {{{#!cplusplus numbers=off |
| Line 351: | Line 448: |
| {{{#!cplusplus | {{{#!cplusplus numbers=off |
| Line 360: | Line 457: |
| {{{#!cplusplus | {{{#!cplusplus numbers=off |
| Line 369: | Line 466: |
| {{{#!cplusplus | {{{#!cplusplus numbers=off |
| Line 378: | Line 475: |
| {{{#!cplusplus | {{{#!cplusplus numbers=off |
Contents
OLE DB 프로그래밍은 COM 구조를 사용하기 때문에 COM 프로그래밍에 대한 이해가 필요하다. 하지만 ATL 의 OLE DB 템플릿 라이브러리를 이용하면 손쉽게 OLE DB 프로그래밍이 가능하다. 따라서 다음은 ATL OLE DB 템플릿 라이브러리를 이용하여 프로그래밍하는 과정을 정리해 본다.
1. 준비 작업 [Bottom] [Top]
OLE DB 프로그래밍에 앞서 사용될 DB 테이블과 저장 프로시저를 생성한다. 각 테이블의 데이터는 임의적으로 생성하여 저장한다.
1.1. DB 테이블 생성 [Bottom] [Top]
-- Account 테이블 생성 --------------------------------------------------------- CREATE TABLE dbo.Account ( [UID] INT IDENTITY(10,1) NOT NULL, [UserID] VARCHAR(32) NOT NULL, [Passwd] VARCHAR(16) NOT NULL ) -- Item 테이블 생성 ------------------------------------------------------------ CREATE TABLE dbo.Item ( [UID] INT NOT NULL, [Col] TINYINT NOT NULL, [ItemID] INT NOT NULL, [Count] TINYINT NOT NULL )
1.2. 저장 프로시저 생성 [Bottom] [Top]
-- 사용자 인증 처리 (사용자 검색, 암호 비교) ----------------------------------- CREATE PROCEDURE dbo.SP_LOGIN_PROC ( @UserID VARCHAR(32) , @Passwd VARCHAR(16) , @UID INT OUTPUT ) AS BEGIN DECLARE @strPWD VARCHAR(16) SET NOCOUNT ON SELECT TOP 1 @strPWD = [Passwd], @UID = [UID] FROM dbo.Account WHERE [UserID] = @UserID IF @strPWD IS NULL BEGIN RETURN 1 -- 사용자 없음 END IF CAST(@strPWD AS VARBINARY) <> CAST(@Passwd AS VARBINARY) BEGIN RETURN 2 -- 암호 불일치 END RETURN 0 -- 인증 완료 END -- 아이템 처리 (사용자 아이템 목록) -------------------------------------------- CREATE PROCEDURE dbo.SP_ITEM_SELECT ( @UID INT ) AS BEGIN SET NOCOUNT ON SELECT Col, ItemID, [Count] FROM dbo.item WHERE [UID] = @UID ORDER BY Col END
2. ATL OLE DB 프로그래밍 과정 [Bottom] [Top]
구현 과정에서 일반적인 쿼리문 (예: SELECT, INSERT, DELETE, UPDATE 문 등) 을 사용할 수 있으나 속도 향상이나 다양한 처리를 위하여 저장 프로시저 (Stored Procedure) 를 사용하였다.
2.1. ATL 헤더 파일 추가 [Bottom] [Top]
ATL OLE DB 소비자 템플릿 라이브러리 헤더 파일을 추가한다.
#include <atldbcli.h>
2.2. 랩퍼 (Wrapper) 클래스 추가 [Bottom] [Top]
- 저장 프로시저 실행을 위한 랩퍼 클래스 추가
- 단순히 저장 프로시저만 실행하고 결과값만 반환 받는 랩퍼 클래스
// QLogin.h : QLogin 쿼리 클래스 선언 // #pragma once // 쿼리 클래스 선언 class QLogin { // 매개변수 선언 public: LONG m_lResult; TCHAR m_szUserID[ 33 ]; TCHAR m_szPasswd[ 17 ]; LONG m_lUID; // 쿼리문 선언 DEFINE_COMMAND_EX( QLogin, OLESTR( "{ ? = CALL dbo.SP_LOGIN_PROC(?,?,?) }" ) ) // 매개변수 맵 선언 BEGIN_PARAM_MAP(QLogin) SET_PARAM_TYPE(DBPARAMIO_OUTPUT) COLUMN_ENTRY(1, m_lResult) SET_PARAM_TYPE(DBPARAMIO_INPUT) COLUMN_ENTRY(2, m_szUserID) SET_PARAM_TYPE(DBPARAMIO_INPUT) COLUMN_ENTRY(3, m_szPasswd) SET_PARAM_TYPE(DBPARAMIO_INPUT | DBPARAMIO_OUTPUT) COLUMN_ENTRY(4, m_lUID) END_PARAM_MAP() }; // 데이터형 선언 typedef CCommand< CAccessor< QLogin > > QUERY_LOGIN;
- 쿼리를 위한 랩퍼 클래스 추가
- 쿼리 (저장 프로시저) 를 통하여 레코드 단위로 데이터를 얻는 랩퍼 클래스
1 // QItemList.h : QItemList 쿼리 클래스 선언 2 // 3 4 #pragma once 5 6 7 // 쿼리 클래스 선언 8 class QItemList 9 { 10 // 데이터열 선언 11 public: 12 BYTE m_bCol; 13 LONG m_lItemID; 14 BYTE m_bCount; 15 16 // 매개변수 선언 17 public: 18 LONG m_lUID; 19 20 // 쿼리문 선언 21 DEFINE_COMMAND_EX( QItemList, OLESTR( "{ CALL dbo.SP_ITEM_SELECT(?) }" ) ) 22 23 // 데이터열 맵 선언 24 BEGIN_COLUMN_MAP(QItemList) 25 COLUMN_ENTRY( 1, m_bCol ) 26 COLUMN_ENTRY( 2, m_lItemID ) 27 COLUMN_ENTRY( 3, m_bCount ) 28 END_COLUMN_MAP() 29 30 // 매개변수 맵 선언 31 BEGIN_PARAM_MAP(QItemList) 32 SET_PARAM_TYPE(DBPARAMIO_INPUT) 33 COLUMN_ENTRY(1, m_lUID) 34 END_PARAM_MAP() 35 }; 36 37 38 // 데이터형 선언 39 typedef CCommand< CAccessor< QItemList > > QUERY_ITEM_LIST;
2.3. COM 초기화 및 데이터베이스 / 세션 연결 과정 [Bottom] [Top]
1 // STEP 1: COM 초기화 2 HRESULT hr = CoInitialize( NULL ); 3 if( FAILED( hr ) ) 4 { 5 // ERROR: COM 초기화 실패 6 // 에러 처리 7 } 8 9 // STEP 2: 데이터베이스 연결 10 //// STEP 2-1: CLSID 얻기 11 CLSID clsid = CLSID_NULL; 12 if( FAILED( CLSIDFromProgID( OLESTR("SQLOLEDB.1"), &clsid ) ) ) 13 { 14 // ERROR: SQLOLEDB CLSID 얻기 실패 15 // 에러 처리 16 } 17 18 //// STEP 2-2: 데이터베이스 연결 준비 19 char szDBstr[ 256 ]; 20 sprintf_s( szDBstr, "Provider=SQLOLEDB.1;Server=%s;Database=%s;UID=%s;PWD=%s", 21 SERVER_STR, // 서버 정보 (주소,포트) 22 DATABASE_STR, // DB 이름 23 UID_STR, // 로그인 정보 (사용자 ID) 24 PWD_STR ); // 암호 25 26 CDBPropSet dbinit( DBPROPSET_DBINIT ); 27 dbinit.AddProperty( DBPROP_INIT_PROMPT, static_cast< short >( 4 ) ); 28 dbinit.AddProperty( DBPROP_INIT_PROVIDERSTRING, szDBstr ); 29 30 //// STEP 2-3: 데이터베이스 연결 시도 31 CDataSource ds; 32 33 hr = ds.Open( clsid, &dbinit ); 34 if( FAILED( hr ) ) 35 { 36 // ERROR: 데이터베이스 연결 실패 37 // 에러 처리 38 } 39 40 // STEP 3: 세션 연결 41 CSession ss; 42 43 hr = ss.Open( ds ); 44 if( FAILED( hr ) ) 45 { 46 // ERROR: 세션 연결 실패 47 // 에러 처리 48 }
2.4. SQL 쿼리 (SQL Query) 실행 [Bottom] [Top]
- 저장 프로시저 실행
1 // 쿼리 객체 정의 2 QUERY_LOGIN login; 3 4 // 쿼리 조건 설정 5 _tcscpy_s( login.m_szUserID, USER_ID ); // USER_ID: 사용자ID 6 _tcscpy_s( login.m_szPasswd, PASSWD ); // PASSWD : 암호 7 8 // 쿼리 실행 9 HRESULT hr = login.Open( ss ); 10 if( FAILED( hr ) ) 11 { 12 // ERROR: 쿼리 실행 실패 13 // 에러 처리 14 } 15 16 // 결과 처리 17 LONG lUID = 0; 18 if( 0 == login.m_lResult ) 19 { 20 lUID = login.m_lUID; 21 } 22 23 printf( "Account: %s, Password: %s ==> UID: %d, Result: %d\n", 24 USER_ID, PASSWD, lUID, login.m_lResult ); 25 26 // 쿼리 해제 27 login.Close();
- 쿼리 실행
1 // 쿼리 객체 정의 2 QUERY_ITEM_LIST itemList; 3 4 // 쿼리 조건 설정 5 itemList.m_lUID = USER_UID; // USER_UID: 사용자 UID 6 7 // 쿼리 실행 8 HRESULT hr = itemList.Open( ss ); 9 if( FAILED( hr ) ) 10 { 11 // ERROR: 쿼리 실행 실패 12 // 에러 처리 13 } 14 15 // 결과 처리 16 printf( ">>> Item List (UID: %d)\n", USER_UID ); 17 18 while( itemList.MoveNext() == S_OK ) 19 { 20 printf( "\tCol: %d, ItemID: %d, Count: %d\n", 21 itemList.m_bCol, itemList.m_lItemID, itemList.m_bCount ); 22 } 23 24 // 쿼리 해제 25 itemList.Close();
2.5. 세션 / 데이터베이스 닫기 및 COM 해제 [Bottom] [Top]
1 // STEP 1: 세션 닫기 2 ss.Close(); 3 4 // STEP 2: 데이터베이스 닫기 5 ds.Close(); 6 7 // STEP 3: COM 해제 8 CoUninitialize();
3. OLE DB 소비자 특성 [Bottom] [Top]
OLE DB Consumer Attributes - The OLE DB consumer attributes inject code, based on the OLE DB Consumer Templates, to create a working OLE DB consumer that performs tasks such as opening tables, executing commands, and accessing data.
특성
설명
db_accessor
Binds columns in a rowset and binds them to the corresponding accessor maps.
db_column
Binds a specified column to the rowset.
db_command
Executes an OLE DB command.
db_param
Associates the specified member variable with an input or output parameter.
db_source
Creates and encapsulates a connection, through a provider, to a data source.
db_table
Opens an OLE DB table.
3.1. OLE DB 소비자 특성을 이용한 프로그래밍 [Bottom] [Top]
- CUserInfo 테이블 쿼리 클래스 선언
// UserInfo.h : CUserInfo 클래스 선언 // #pragma once [ db_table( L"dbo.UserInfo" ) ] class CUserInfo { public: [ db_column(1) ] LONG m_ID; [ db_column(2) ] TCHAR m_Name[21]; [ db_column(3) ] SHORT m_Age; [ db_column(4) ] TCHAR m_Phone[14]; };
- 프로그래밍 과정
1 // ATL OLE DB 소비자 템플릿 라이브러리 헤더 파일 2 #include <atldbcli.h> 3 4 //------------------------------------------------------------------------------ 5 // STEP 1: COM 초기화 6 HRESULT hr = CoInitialize( NULL ); 7 if( FAILED( hr ) ) 8 { 9 // ERROR: COM 초기화 실패 10 // 에러 처리 11 } 12 13 //------------------------------------------------------------------------------ 14 // STEP 2: 데이터베이스 연결 15 CDataConnection dbConn; 16 17 WCHAR szDbStr[ 256 ]; 18 swprintf( szDbStr, L"Provider=SQLOLEDB.1;Data Source=%s;User ID=%s;Password=%s&;Initial Catalog=%s;", 19 SERVER_STR, // 서버 정보 (주소,포트) 20 UID_STR, // 로그인 정보 (사용자 ID) 21 PWD_STR, // 암호 22 DATABASE_STR ); // DB 이름 23 24 hr = dbConn.Open( szDbStr ); 25 if( FAILED( hr ) ) 26 { 27 // ERROR: 데이터베이스 연결 실패 28 // 에러 처리 29 } 30 31 //------------------------------------------------------------------------------ 32 // STEP 3: 쿼리 실행 33 CUserInfo tblUserInfo; 34 35 hr = tblUserInfo.OpenRowset( dbConn.m_session ); 36 if( FAILED( hr ) ) 37 { 38 // ERROR: 쿼리 실행 실패 39 // 에러 처리 40 } 41 42 while( S_OK == tblUserInfo.MoveNext() ) 43 { 44 printf( "ID\t: %d\n", tblUserInfo.m_ID ); 45 printf( "Name\t: %s\n", tblUserInfo.m_Name ); 46 printf( "Age\t: %d\n", tblUserInfo.m_Age ); 47 printf( "Phone\t: %s\n", tblUserInfo.Phone ); 48 } 49 50 //------------------------------------------------------------------------------ 51 // STEP 4: 쿼리 해제 & 데이터베이스 연결 닫기 52 tblUserInfo.Close(); 53 dbConn.CloseDataSource(); 54 55 // STEP 5: COM 해제 56 CoUninitialize();
4. ATL OLE DB 클래스 구조 [Bottom] [Top]
데이터 소스 및 세션 클래스
접근자 클래스
행 집합 클래스
명령 및 테이블 클래스
5. OLE DB Provider & CLSID 관련 정보 [Bottom] [Top]
Microsoft OLE DB Provider for SQL Server
- sqloledb.dll
- SQLOLEDB.1
#include <sqloledb.h> CLSID CLSID_SQLOLEDB = {0xC7FF16CL,0x38E3,0x11D0,{0x97,0xAB,0x0,0xC0,0x4F,0xC2,0xAD,0x98}};
Microsoft OLE DB Provider for Oracle
- msdaora.dll
- msdaora
#include <msdaora.h> CLSID CLSID_MSDAORA = {0xE8CC4CBE,0xFDFF,0x11D0,{0xB8,0x65,0x00,0xA0,0xC9,0x08,0x1C,0x1D}};
Oracle Provider for OLE DB
- OraOLEDB.dll
- OraOLEDB.Oracle.1
#include "OraOLEDB.h" CLSID CLSID_OraOLEDB = {0x3F63C36E,0x51A3,0x11D2,{0xBB,0x7D,0x00,0xC0,0x4F,0xA3,0x00,0x80}};
Microsoft Data Access - OLE DB Provider for ODBC Drivers
- msdasql.dll
- MSDASQL.1
#include <msdasql.h> CLSID CLSID_MSDASQL = {0xC8B522CBL,0x5CF3,0x11CE,{0xAD,0xE5,0x00,0xAA,0x00,0x44,0x77,0x3D}};
Microsoft Data Access - OLE DB Simple Provider
- msdaosp.dll
- MSDAOSP.1
#include <msdaosp.h> CLSID CLSID_MSDAOSP = {0xDFC8BDC0,0xE378,0x11D0,{0x9B,0x30,0x0,0x80,0xC7,0xE9,0xFE,0x95}};
