CDaoDatabase
MFC에서 지원하는 DAO 클래스
네트워크 접속 미지원
deprecated 상태이므로 사용 비권장
컴파일시 경고는 다음과 같습니다.
warning C4995: 'CDaoDatabase': name was marked as #pragma deprecated
경고가 보기 싫다면 다음 코드로 무시할 수 있습니다.
#pragma warning(disable:4995)
MFC에서 제공하는 DAO 관련 클래스 (전부 deprecated)
CDaoWorkspace : 하나이상의 CDaoDatabase 객체에 대한 트랜잭션 관리용
CDaoDatabase : DB 연결용
CDaoRecordset : DB 레코드셋 저장용
CDaoRecordView : CFormView 기반의 레코드셋 뷰 제공
CDaoTableDef : 테이블 정보 저장용
CDaoTableDefInfo : TableDef 객체 정보를 갖는 구조체
CDaoQueryDef : DB 쿼리, 연결정보 등 저장
CDaoFieldInfo : Field 객체 정보를 갖는 구조체
CDaoIndexInfo : Index 객체 정볼르 갖는 구조체
CDaoFieldExchange : DB간 데이터 교환 지원하는 레코드셋
COleVariant : DAO 객체의 데이터형
CByteArray : blob 데이터 처리용
CDaoException : Dao 관련 exception 클래스
DAO 관련 MSDN
테스트 샘플
DB 파일 (.mdb)
테스트 샘플 코드
void CTestDlg::OnBnClickedButton1()
{
CDaoDatabase* database = NULL;
CDaoTableDef* tableDef = NULL;
TCHAR mdb[256] = _T("c:\\test.mdb");
TRY
{
//db 오픈
database = new CDaoDatabase;
database->Open(mdb);
{
//테이블 개수 확인
int tableCnt = database->GetTableDefCount();
CString strTableCnt;
strTableCnt.Format(_T("테이블 개수 : %d"), tableCnt);
AfxMessageBox(strTableCnt);
//전체 테이블 목록보기
CString tableNames;
for (int i = 0; i < tableCnt; i++)
{
//테이블 정보 가져오기
CDaoTableDefInfo tableDefInfo;
database->GetTableDefInfo(i, tableDefInfo, AFX_DAO_ALL_INFO); //첫번째 테이블
if (tableDefInfo.m_lAttributes & dbSystemObject) //시스템 테이블인 경우
tableNames += _T("시스템 테이블 : ");
else
tableNames += _T("사용자 테이블 : ");
tableNames += tableDefInfo.m_strName; //테이블 이름
tableNames += _T("\n");
}
AfxMessageBox(tableNames);
}
//테이블 정보 보기
{
tableDef = new CDaoTableDef(database);
tableDef->Open(_T("test_table")); //album이라는 테이블
CString info = _T("");
//테이블 이름
info += tableDef->GetName();
info += _T("\n");
//테이블 생성일
COleDateTime oleCTime = tableDef->GetDateCreated();
CString createTime;
createTime.Format(_T("생성일: %04d-%02d-%02d\n"), oleCTime.GetYear(), oleCTime.GetMonth(), oleCTime.GetDay());
info += createTime;
//테이블 마지막 수정일
COleDateTime oleUTime = tableDef->GetDateLastUpdated();
CString lastUpdatedTime;
lastUpdatedTime.Format(_T("수정일: %04d-%02d-%02d\n"), oleUTime.GetYear(), oleUTime.GetMonth(), oleUTime.GetDay());
info += lastUpdatedTime;
//테이블 레코드 수
CString recordCnt;
recordCnt.Format(_T("레코드수: %ld\n"), tableDef->GetRecordCount());
info += recordCnt;
//테이블 필드 출력
info += _T("필드정보\n");
CDaoFieldInfo fieldInfo;
int fieldCnt = tableDef->GetFieldCount();
for (int i = 0; i < fieldCnt; i++)
{
tableDef->GetFieldInfo(i, fieldInfo, AFX_DAO_ALL_INFO);
info += _T("\t");
info += fieldInfo.m_strName; //필드 이름
info += _T(" : ");
short nType = fieldInfo.m_nType; //필드 타입
switch (nType)
{
case dbBoolean: info += _T("BOOLEAN"); break;
case dbByte: info += _T("BYTE"); break;
case dbInteger: info += _T("INTEGER"); break;
case dbLong: info += _T("LONG"); break;
case dbSingle: info += _T("SINGLE"); break;
case dbCurrency: info += _T("CURRENCY"); break;
case dbDate: info += _T("DATE"); break;
case dbDouble: info += _T("DOUBLE"); break;
case dbText: info += _T("TEXT"); break;
case dbLongBinary: info += _T("LONGBINARY"); break;
case dbMemo: info += _T("MEMO"); break;
}
info += _T("\n");
}
//인덱스 필드 찾기
info += _T("인덱스 필드\n");
CDaoIndexInfo indexInfo;
int indexCnt = tableDef->GetIndexCount();
for (int i = 0; i < indexCnt; i++)
{
tableDef->GetIndexInfo(i, indexInfo);
for (int j = 0; j < indexInfo.m_nFields; j++)
{
CString indexField = indexInfo.m_pFieldInfos[j].m_strName;
info += _T("\t");
info += indexField;
info += _T("\n");
}
}
AfxMessageBox(info);
}
//쿼리 실행
{
CDaoRecordset rs(database);
rs.Open(AFX_DAO_USE_DEFAULT_TYPE, _T("select count(*) as cnt from test_table")); //쿼리 실행
COleVariant var;
rs.GetFieldValue(_T("cnt"), var); //쿼리 값 획득
rs.Close();
CString value = convertString(var);
AfxMessageBox(value);
}
//바인딩 쿼리 실행 : select
{
//바인딩 형식의 쿼리 저장
CDaoQueryDef qd(database);
/* qd.Create()의 첫번째 인수의 문자로 쿼리가 저장되며 qd.Append()로 저장이 완료됨.
(영구저장되는 위치가 레지스트리 같긴한데 잘 모르겠습니다.)
한번쓰는 임시 쿼리인 경우 NULL을 준후 qd.Append()를 안해주면 됩니다.*/
qd.Create(NULL, _T("PARAMETERS [binding 1] INT; select * from test_table where 1 = [binding 1]"));
//qd.Append(); //영구적인 쿼리 저장
//바인딩
COleVariant binding1((short)1);
qd.SetParamValue(_T("[binding 1]"), binding1);
//쿼리 실행
CDaoRecordset rs(database);
rs.Open(&qd);
CString rst;
while (!rs.IsEOF())
{
int cnt = rs.GetFieldCount();
COleVariant var;
for (int i = 0; i < cnt; i++)
{
rs.GetFieldValue(i, var);
rst += convertString(var);
rst += _T(", ");
}
rst += _T("\n");
rs.MoveNext(); //scroll
}
AfxMessageBox(rst);
qd.Close();
//qd.m_pDAOQueryDef->Close();
}
}
CATCH(CException, e) //예외처리 : 정확히는 CDaoException이지만 어짜피 CException 상속 클래스임.
{
TCHAR szCause[256];
e->GetErrorMessage(szCause, 256);
AfxMessageBox(szCause, MB_ICONERROR);
}
END_CATCH
if (tableDef != NULL)
{
if (tableDef->IsOpen()) tableDef->Close();
delete tableDef;
tableDef = NULL;
}
if (database != NULL)
{
if (database->IsOpen()) database->Close();
delete database;
database = NULL;
}
}
//COleVariant를 CString으로 변환해줄 함수
CString CTestDlg::convertString(COleVariant& var)
{
CString value;
switch (var.vt) //COleVariant를 CString으로 변경
{
case VT_EMPTY:
case VT_NULL: value = _T("NULL"); break;
case VT_I2: value.Format(_T("%hd"), V_I2(&var)); break;
case VT_I4: value.Format(_T("%d"), V_I4(&var)); break;
case VT_R4: value.Format(_T("%e"), (double)V_R4(&var)); break;
case VT_R8: value.Format(_T("%e"), V_R8(&var)); break;
case VT_CY: value = COleCurrency(var).Format(); break;
case VT_DATE: value = COleDateTime(var).Format(_T("%m %d %y")); break;
case VT_BSTR: value = V_BSTRT(&var); break;
case VT_DISPATCH: value = _T("VT_DISPATCH"); break;
case VT_ERROR: value = _T("VT_ERROR"); break;
case VT_BOOL: V_BOOL(&var) ? value = _T("TRUE") : value = _T("FALSE"); break;
case VT_VARIANT: value = _T("VT_VARIANT"); break;
case VT_UNKNOWN: value = _T("VT_UNKNOWN"); break;
case VT_I1: value = _T("VT_I1"); break;
case VT_UI1: value.Format(_T("0x%02hX"), (unsigned short)V_UI1(&var)); break;
case VT_UI2: value = _T("VT_UI2"); break;
case VT_UI4: value = _T("VT_UI4"); break;
case VT_I8: value = _T("VT_I8"); break;
case VT_UI8: value = _T("VT_UI8"); break;
case VT_INT: value = _T("VT_INT"); break;
case VT_UINT: value = _T("VT_UINT"); break;
case VT_VOID: value = _T("VT_VOID"); break;
case VT_HRESULT: value = _T("VT_HRESULT"); break;
case VT_PTR: value = _T("VT_PTR"); break;
case VT_SAFEARRAY: value = _T("VT_SAFEARRAY"); break;
case VT_CARRAY: value = _T("VT_CARRAY"); break;
case VT_USERDEFINED: value = _T("VT_USERDEFINED"); break;
case VT_LPSTR: value = _T("VT_LPSTR"); break;
case VT_LPWSTR: value = _T("VT_LPWSTR"); break;
case VT_FILETIME: value = _T("VT_FILETIME"); break;
case VT_BLOB: value = _T("VT_BLOB"); break;
case VT_STREAM: value = _T("VT_STREAM"); break;
case VT_STORAGE: value = _T("VT_STORAGE"); break;
case VT_STREAMED_OBJECT: value = _T("VT_STREAMED_OBJECT"); break;
case VT_STORED_OBJECT: value = _T("VT_STORED_OBJECT"); break;
case VT_BLOB_OBJECT: value = _T("VT_BLOB_OBJECT"); break;
case VT_CF: value = _T("VT_CF"); break;
case VT_CLSID: value = _T("VT_CLSID"); break;
}
WORD vt = var.vt;
if (vt & VT_ARRAY)
{
vt = vt & ~VT_ARRAY;
value = _T("Array of ");
}
if (vt & VT_BYREF)
{
vt = vt & ~VT_BYREF;
value += _T("Pointer to ");
}
if (vt != var.vt)
{
switch (vt)
{
case VT_EMPTY: value += _T("VT_EMPTY"); break;
case VT_NULL: value += _T("VT_NULL"); break;
case VT_I2: value += _T("VT_I2"); break;
case VT_I4: value += _T("VT_I4"); break;
case VT_R4: value += _T("VT_R4"); break;
case VT_R8: value += _T("VT_R8"); break;
case VT_CY: value += _T("VT_CY"); break;
case VT_DATE: value += _T("VT_DATE"); break;
case VT_BSTR: value += _T("VT_BSTR"); break;
case VT_DISPATCH: value += _T("VT_DISPATCH"); break;
case VT_ERROR: value += _T("VT_ERROR"); break;
case VT_BOOL: value += _T("VT_BOOL"); break;
case VT_VARIANT: value += _T("VT_VARIANT"); break;
case VT_UNKNOWN: value += _T("VT_UNKNOWN"); break;
case VT_I1: value += _T("VT_I1"); break;
case VT_UI1: value += _T("VT_UI1"); break;
case VT_UI2: value += _T("VT_UI2"); break;
case VT_UI4: value += _T("VT_UI4"); break;
case VT_I8: value += _T("VT_I8"); break;
case VT_UI8: value += _T("VT_UI8"); break;
case VT_INT: value += _T("VT_INT"); break;
case VT_UINT: value += _T("VT_UINT"); break;
case VT_VOID: value += _T("VT_VOID"); break;
case VT_HRESULT: value += _T("VT_HRESULT"); break;
case VT_PTR: value += _T("VT_PTR"); break;
case VT_SAFEARRAY: value += _T("VT_SAFEARRAY"); break;
case VT_CARRAY: value += _T("VT_CARRAY"); break;
case VT_USERDEFINED: value += _T("VT_USERDEFINED"); break;
case VT_LPSTR: value += _T("VT_LPSTR"); break;
case VT_LPWSTR: value += _T("VT_LPWSTR"); break;
case VT_FILETIME: value += _T("VT_FILETIME"); break;
case VT_BLOB: value += _T("VT_BLOB"); break;
case VT_STREAM: value += _T("VT_STREAM"); break;
case VT_STORAGE: value += _T("VT_STORAGE"); break;
case VT_STREAMED_OBJECT: value += _T("VT_STREAMED_OBJECT"); break;
case VT_STORED_OBJECT: value += _T("VT_STORED_OBJECT"); break;
case VT_BLOB_OBJECT: value += _T("VT_BLOB_OBJECT"); break;
case VT_CF: value += _T("VT_CF"); break;
case VT_CLSID: value += _T("VT_CLSID"); break;
}
}
return value;
}
'C++' 카테고리의 다른 글
POSA (Pattern-Oriented Software Architecture) (0) | 2011.01.03 |
---|---|
ACE (ADAPTIVE Communication Environment) (0) | 2011.01.03 |
UML class 관계 표기법 (1) | 2011.01.03 |
ActiveX Control Test Container : Visual Studio 2008 (0) | 2010.12.09 |
[MFC] 다른 윈도우 찾기 (0) | 2010.12.09 |
[MFC] 메뉴 제거, 타이틀 제거, 캡션 변경. 창 크기 설정 방법 (0) | 2010.12.09 |
[MFC] splitter UI 바꾸기 (0) | 2010.12.09 |
[MFC] CTreeView에 바탕화면 폴더 트리 생성 예제 (0) | 2010.12.03 |