| ADOを使ったデータベースアクセス |
#define INITGUID // これはADOを定義するための定数(GUID)の初期化
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" rename_namespace("ADOCG") rename("EOF", "EndOfFile")
using namespace ADOCG; // 名前空間
#include "icrsint.h" // ADOを使って取得したフィールドのデータを変換するマクロなどが定義されたヘッダー
/////////////////////////////////////////////////////////////////////////////
// CUKAdoTestDlg ダイアログ
class CUKAdoTestDlg : public CDialog
{
……
private:
_ConnectionPtr m_pConnect; // Connectionオブジェクト
_CommandPtr m_pCommand; // Commandオブジェクト
_RecordsetPtr m_pRecordset; // Recordsetオブジェクト
};
BOOL CUKAdoTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
……
try {
// COMの初期化処理
::CoInitialize(NULL);
// ADOオブジェクトの生成
m_pConnect.CreateInstance(__uuidof(Connection));
m_pCommand.CreateInstance(__uuidof(Command));
m_pRecordset.CreateInstance(__uuidof(Recordset));
// データベースへの接続
m_pConnect->Open(
L"Provider=MSDASQL.1;Data Source=TEXTDATABASE",
L"", L"", adOpenUnspecified);
// SQLの設定
m_pCommand->ActiveConnection = m_pConnect;
m_pCommand->CommandText = "SELECT * FROM MyData.csv";
m_pRecordset->PutRefSource(m_pCommand);
// レコードセットの取得
_variant_t vNull; // VARIANT型のNULLとして使う
vNull.vt = VT_ERROR;
vNull.scode = DISP_E_PARAMNOTFOUND;
m_pRecordset->Open(vNull, vNull, adOpenDynamic, adLockOptimistic, adCmdUnknown);
// 先頭レコードへ移動し、フィールドの値を取得
m_pRecordset->MoveFirst();
DisplayField();
}
catch(_com_error &e)
{
MessageBox(e.Description());
return TRUE;
}
return TRUE; // TRUE を返すとコントロールに設定したフォーカスは失われません。
}
// WM_DESTROYメッセージハンドラ
void CUKAdoTestDlg::OnDestroy()
{
CDialog::OnDestroy();
// TODO: この位置にメッセージ ハンドラ用のコードを追加してください
m_pRecordset->Close();
m_pConnect->Close();
m_pConnect = 0;
m_pCommand = 0;
m_pRecordset = 0;
::CoUninitialize();
}
void CUKAdoTestDlg::DisplayField()
{
try {
_variant_t vString;
vString = m_pRecordset->GetCollect(_variant_t("ID"));
vString.ChangeType(VT_I4);
m_iID = vString.iVal;
vString = m_pRecordset->GetCollect(_variant_t("RaceName"));
vString.ChangeType(VT_BSTR);
m_strRaceName = vString.bstrVal;
vString = m_pRecordset->GetCollect(_variant_t("Distance"));
vString.ChangeType(VT_BSTR);
m_strDistance = vString.bstrVal;
UpdateData(FALSE);
}
catch(_com_error &e)
{
MessageBox(e.Description());
}
}
void CUKAdoTestDlg::OnButtonNext()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
// ここでもtry〜catchで例外処理をおこなうべき!
m_pRecordset->MoveNext();
if( m_pRecordset->GetEndOfFile() )
{
m_pRecordset->MoveLast();
}
DisplayField();
}
void CUKAdoTestDlg::OnButtonPrev()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
// ここでもtry〜catchで例外処理をおこなうべき!
m_pRecordset->MovePrevious();
if( m_pRecordset->GetBOF() )
{
m_pRecordset->MoveFirst();
}
DisplayField();
}
これで、「<<」ボタンと「>>」ボタンを使ってデータベースの各レコードを順次表示することが可能となる。
m_pRecordset->Open(vNull, vNull, adOpenStatic, adLockBatchOptimistic, adCmdUnknown);レコードセットに対する処理はそれぞれ以下のようになる。
// カレントレコードの削除
// 削除後はカレントレコードを他のレコードへ移動させること
m_pRecordset->Delete(adAffectCurrent);
// カレントレコードの"RaceName"フィールドを更新する
UpdateData(TRUE);
_variant_t vName, vValue;
vName.SetString("RaceName");
vValue.SetString(m_strRaceName);
m_pRecordset->Update(vName, vValue);
// レコードを新規作成する
// 他のフィールドもUpdateを使って値を設定すること(更新時の方法で)
_variant_t vName, vValue;
vName.SetString("RaceName");
vValue.SetString("(新規レコード)");
m_pRecordset->AddNew(vName, vValue);
データベースを一括して更新する方法の場合、上記の方法ではレコードセットが更新されるだけである。
更新したレコードセットの内容をデータベースに反映させるには、以下の処理をおこなう。
m_pRecordset->UpdateBatch(adAffectAllChapters); // 新規作成時は以下の処理もおこなうこと m_pRecordset->Requery(adCmdUnknown); m_pRecordset->MoveLast();