vcでado接続accessデータベース

8714 ワード

直接ADOを通じてアクセスデータベースを操作する著者/徐景周私は『VC知識ベースオンライン雑誌』第14期と第15期に2つの文章を発表したことがある--「直接ODBCを通じてExcel表ファイルを読む、書く」と「直接DAOを通じてアクセスファイルを読む、書く」、前後してODBCとDAOの2種類のデータベースアクセス技術の基本的な使用方法を紹介した.今回はADOデータベースアクセス技術の使い方をご紹介します.ADO(Active Data Object、アクティブデータオブジェクト)は、実際にはCOM(コンポーネントオブジェクトモデル)ベースの自動化インタフェース(IDispatch)技術であり、OLE DB(オブジェクト接続と埋め込まれたデータベース)をベースにOLE DBで丹念にパッケージされたデータベースアクセス技術を用いて、データベースアプリケーションを迅速に作成することができます.ADOは、一般的に一般的なデータアクセスの詳細をカプセル化する非常に簡単なオブジェクトのセットを提供します.ODBCデータソースは一般的なOLE DB Prividerも提供するため、ADOは独自のOLE DB Prividerだけでなく、すべてのODBCドライバを適用することができる.OLE DBやADOの他の詳細については、読者が自分で関連書籍やMSDNを閲覧することができますが、ここでは説明しません.ADOというデータベース・アクセス・テクノロジーをどのように把握するかをテーマに直接進みましょう.ADOの操作方法は前述のDAOの操作と多くの点で類似点があるが,ここで筆者はその使用方法をより効果的に説明するためにVC 6を用いた.0は、ADOによってアクセスデータベースを直接操作できるAdoRWAccessの例を示したプログラムである.例のプログラムの実行効果は下図のように、例のプログラムでは元のライブラリ構造、データベース名Demoを採用している.mdbは、ライブラリ内のテーブル名DemoTable、テーブル内のフィールド名Name(名前)とAge(年齢)の2つのフィールドで、サンプルプログラム操作に必要なAccessデータベースを構築します.これは、前の2つの記事のサンプルソースコードのライブラリ構造と互換性があります.次に、ADOデータベースアクセス技術で使用する基本的な手順と方法を見てみましょう.まず、ADOをサポートするコンポーネントタイプライブラリ(*.tlb)をimport文で参照します.タイプライブラリは、実行可能プログラム(DLL、EXEなど)の一部として、msado 15に配置することができます.dllの付属リソースでは、#importで直接参照するだけでよい.Stdafxで直接hファイルに次の文を加えて実現する.
#import "c:/program files/common files/system/ado/msado15.dll" /
	no_namespace /
	rename ("EOF", "adoEOF")          

パス名は、自分のシステムにインストールされているADOサポートファイルのパスに応じて、自分で設定できます.コンパイラが#import文に遭遇すると、参照コンポーネントタイプライブラリのインタフェースにパッケージクラスが生成されます.#import文は、実際にはAPIの内容LoadTypeLib()が実行されていることに相当します.import文は、プロジェクト実行可能プログラム出力ディレクトリに*という2つのファイルを生成する.tlh(タイプライブラリヘッダファイル)および*tli(タイプライブラリ実装ファイル)は、各インタフェースにスマートポインタを生成し、様々なインタフェースメソッド、列挙タイプ、CLSIDなどを宣言し、一連のパッケージメソッドを作成します.文no_namespaceは、ADOオブジェクトがネーミングスペースを使用しないことを示し、rename(「EOF」,「adoEOF」)は、他のライブラリのネーミングと競合しないように、ADOの終了フラグEOFをadoEOFに変更することを示します.次に、プログラムの初期化中にコンポーネントを初期化する必要があり、一般的にCoInitialize(NULL)を使用することができる.これにより、この方法は、終了時に初期化されたCOMを閉じるために、次の文CoUnInitialize()を使用することができる.実現します.MFCでは、AfxOleInit()と、AfxOleInit()と、AfxOleInit()と、AfxOleInit()と、AfxOleInit()と、AfxOleInit()と、AfxOleInit()と、AfxOleInit()と、AfxOleInit()と、AfxOleInit()と、AfxO次に、ADOの操作をそのまま使用することができます.私たちがよく使うのは、前に#import文でタイプライブラリを参照したときに生成されたパッケージクラスだけです.tlhで宣言されたスマートポインタの3つは、それぞれ_ConnectionPtr、_RecordsetPtrと_CommandPtr.それぞれの使い方を紹介します.1、ConnectionPtrインテリジェントポインタは、通常、ライブラリ接続を開いたり閉じたり、そのExecuteメソッドを使用して結果を返さないコマンド文を実行したりします(使用方法は_CommandPtrのExecuteメソッドと似ています).ライブラリ接続を開きます.インスタンスポインタを作成してからOpenでライブラリ接続を開き、IUnknownの自動化インタフェースポインタを返します.コードは次のとおりです.
_ConnectionPtr	m_pConnection;
//    COM,  ADO     
AfxOleInit();
m_pConnection.CreateInstance(__uuidof(Connection));

//  ADO           try...catch()       ,
//                    。jingzhou xu
try                 
{	
	//     Access Demo.mdb
	m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Demo.mdb","","",adModeUnknown);
}
catch(_com_error e)
{
	AfxMessageBox("       ,     Demo.mdb        !");
	return FALSE;
}      

-ライブラリ接続を閉じます.接続ステータスが有効な場合は、Closeメソッドで閉じ、空の値を割り当てます.コードは次のとおりです.
if(m_pConnection->State)
        m_pConnection->Close();
m_pConnection= NULL;      

2、_RecordsetPtrスマートポインタは、ライブラリ内のデータテーブルを開くことができ、テーブル内のレコード、フィールドなどをさまざまに操作することができます.--データテーブルを開きます.ライブラリ内のテーブル名DemoTableというデータテーブルを開きます.コードは次のとおりです.
_RecordsetPtr	m_pRecordset;
m_pRecordset.CreateInstance(__uuidof(Recordset));

//  ADO           try...catch()       ,
//                    。jingzhou xu
try
{
	m_pRecordset->Open("SELECT * FROM DemoTable",                //   DemoTable      
						theApp.m_pConnection.GetInterfacePtr(),	 //       IDispatch  
						adOpenDynamic,
						adLockOptimistic,
						adCmdText);
}
catch(_com_error *e)
{
	AfxMessageBox(e->ErrorMessage());
}      

——表内データを読みだします.テーブル内のデータを全て読み出してリストボックスに表示する、m_AccessListはリストボックスのメンバー変数名です.テーブル終了フラグadoEOFに遭遇しない場合は、GetCollect(フィールド名)またはm_pRecordset->Fields->GetItem(フィールド名)->Valueメソッドは、現在のレコードポインタが指すフィールド値を取得し、MoveNext()メソッドで次のレコード位置に移動します.コードは次のとおりです.
_variant_t var;
CString strName,strAge;
	try
	{
		if(!m_pRecordset->BOF)
			m_pRecordset->MoveFirst();
		else
		{
			AfxMessageBox("      ");
			return;
		}

		//               
		while(!m_pRecordset->adoEOF)
		{
			var = m_pRecordset->GetCollect("Name");
			if(var.vt != VT_NULL)
				strName = (LPCSTR)_bstr_t(var);
			var = m_pRecordset->GetCollect("Age");
			if(var.vt != VT_NULL)
				strAge = (LPCSTR)_bstr_t(var);

			m_AccessList.AddString( strName + " --> "+strAge );

			m_pRecordset->MoveNext();
		}

		//          ,           
		m_AccessList.SetCurSel(0);
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}     

-レコードを挿入します.まずAddNew()メソッドで空のレコードを追加し、PutCollect(フィールド名、値)で各フィールドの値を入力し、最後にUpdate()をライブラリ内のデータに更新することもできます.変数m_Nameとm_Ageは、名前および年齢編集ボックスのメンバー変数名です.コードは次のとおりです.
try
	{
		//       
		m_pRecordset->AddNew();
		m_pRecordset->PutCollect("Name", _variant_t(m_Name));
		m_pRecordset->PutCollect("Age", atol(m_Age));
		m_pRecordset->Update();

		AfxMessageBox("    !");
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}      

-記録ポインタを移動します.移動記録ポインタは、MoveFirst()メソッドにより1番目の記録に移動し、MoveLast()メソッドにより最後の記録に移動し、MovePrevious()メソッドにより現在の記録の前の記録に移動し、MoveNext()メソッドにより現在の記録の次の記録に移動することができる.しかし、記録ポインタを任意の記録位置に勝手に移動させる必要がある場合には、現在の記録に対してポインタ位置を移動させるMove()法、正の値を後ろに移動させ、負の値を前に移動させるMove(3)、現在の記録が3の場合に記録3から後ろに3つの記録位置を移動させるMove(記録番号)法を用いることが多い.コードは次のとおりです.
	try
	{
		int curSel = m_AccessList.GetCurSel();	
		//            ,                     
		m_pRecordset->MoveFirst();
		m_pRecordset->Move(long(curSel));
		
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}      

-レコードのフィールド値を変更します.レコードポインタを変更する場所に移動し、PutCollect(フィールド名、値)で直接新しい値を書き込み、Update()でデータベースを更新することもできます.上記の方法でレコードポインタを移動し、フィールド値コードを変更することは以下のようになります.
	try
	{
		//             
		m_pRecordset->MoveFirst();
		m_pRecordset->Move(1);        //  0  
		m_pRecordset->PutCollect("Name", _variant_t(m_Name));
		m_pRecordset->PutCollect("Age", atol(m_Age));
		m_pRecordset->Update();
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}      

-レコードを削除します.レコードの削除は、上記の変更レコードと同様に、まずレコードポインタを変更する場所に移動し、直接Delete()メソッドで削除し、Update()でデータベースを更新してもよい.コードは次のとおりです.
	try
	{
		//          
		m_pRecordset->MoveFirst();
		m_pRecordset->Move(1);        //  0  
		m_pRecordset->Delete(adAffectCurrent);  //   adAffectCurrent       
		m_pRecordset->Update();
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}      

-レコードセットを閉じます.レコードセットをCloseメソッドで直接閉じ、空の値を割り当てます.コードは次のとおりです.
	m_pRecordset->Close();
	m_pRecordset = NULL;      

3、CommandPtrスマートポインタ、使用可能_ConnectionPtrまたは_RecordsetPtrは、タスクを実行し、出力パラメータを定義し、ストアド・プロシージャまたはSQL文を実行します.-SQL文を実行します.まず_を作成します.CommandPtrインスタンスポインタは、ライブラリ接続とSQL文をパラメータとしてExecute()メソッドを実行できます.コードは次のとおりです.
_CommandPtr		m_pCommand;
m_pCommand.CreateInstance(__uuidof(Command));
m_pCommand->ActiveConnection = m_pConnection;  //        
m_pCommand->CommandText = "SELECT * FROM DemoTable";  // SQL  
m_pRecordset = m_pCommand->Execute(NULL, NULL,adCmdText); //   SQL  ,           

-ストレージ・プロシージャを実行します.ストアド・プロシージャを実行する操作は、前述のSQL文と同様です.異なる点は、CommandTextパラメータでSQL文ではなく、Demoなどのストアド・プロシージャの名前です.もう1つの違いは、Execute()のパラメータをadCmdText(SQL文の実行)からadCmdStoredProcに変更してストレージ・プロシージャを実行することです.ストレージ中に入出力パラメータが存在する場合は、別のスマートポインタ_を使用する必要があります.ParameterPtrは、入力、出力するパラメータ情報を逐次設定し、_に付与するCommandPtrのParametersパラメータで情報を伝達し、興味のある読者は自分で関連書籍やMSDNを検索することができます.ストアド・プロシージャを実行するコードは次のとおりです.
_CommandPtr		m_pCommand;
m_pCommand.CreateInstance(__uuidof(Command));
  m_pCommand->ActiveConnection = m_pConnection;  //        
m_pCommand->CommandText = "Demo";  
  m_pCommand->Execute(NULL,NULL, adCmdStoredProc);