この特集のトップページへ
>
Appendix A:ADOコンポーネントによるデータベースアクセス
A.3 ADODB.Connectionを使ったデータベースアクセス
では次に,データベーステーブルの操作について説明する。
ADOを使う場合,データベーステーブルを操作する方法として,ADODB.ConnectionオブジェクトのExecuteメソッドを使う方法と,ADODB.RecordsetオブジェクトのOpenメソッドを使う方法がある。まずは,ADODB.ConnectionオブジェクトのExecuteメソッドを使う方法から説明する。
A.3.1 Executeメソッドの実行
ADOを使ってデータベーステーブルを操作する場合,テーブルをまるごと取得する方法とSQL文を発行する方法の2通りがある(それ以外に,データベース内のストアドプロシージャを呼び出す方法などもあるが,それらについては割愛する)。
1)テーブルをまるごと取得する方法
まずは,テーブルに含まれるレコードをすべて取得する方法について説明する。ADOの場合,取得したレコードはADODB.Recordsetオブジェクトに返される。そのため,結果を受け取るADODB.Recordsetオブジェクトを格納する変数を,あらかじめDim文で宣言しておく。
Dim objRec As ADODB.Recordset
そして,次のようにしてADODB.ConnectionオブジェクトのExecuteメソッドを呼び出す。
Set objRec = objCon.Execute("テーブル名",,adCmdTable)
※最後の引数adCmdTableは省略することができる。
ただし,その場合,どのような指示であるのかをデータベース
プロバイダが自動評価するので,処理速度が若干低下する。
これで,指定したテーブルに含まれるすべてのレコードが変数objRecに格納される。格納されたレコードを操作する方法については,すぐあとに説明する。
なお,ADODB.ConnectionオブジェクトのExecuteメソッドを呼び出して取得したADODB.Recordsetオブジェクトは,前方方向にしか進むことができず,また書き込めない,読み取り専用の前方スクロールタイプカーソルである。そのため,取得したobjRec変数の内容を操作して,データを書き換え,それをテーブルに書き戻すことはできない。書き込み可能なADODB.Recordsetオブジェクトを取得するには,ADODB.RecordsetオブジェクトのOpenメソッドを用いる必要がある(この方法については「A.4 ADODB.Recordsetを使ったデータベースアクセス」で説明する)。
2)SQLを発行する方法
次にSQL(Structure Query Language:構造化問い合わせ言語)文を発行する方法について説明する。SQLとは,データベースを操作するための構造化された言語で,CREATE文,SELECT文,INSERT文,DELETE文,UPDATE文の5つの基本構文を使って,データベースに対して各種の操作を実行するものである(SQLの構文を「Appendix B SQLの基本文法」として簡単にまとめてあるので,SQLに詳しくない人は参照してほしい)。
SQL文を発行する場合にも,ADODB.ConnectionオブジェクトのExecuteメソッドを利用する。ただし,そのSQL文が結果を返すか否かによって,呼び出し方は異なる。結果を返す場合とはSELECT文を実行する場合を指し,結果を返さない場合とはSELECT文以外を実行する場合を指す。
(a) 結果を返す場合(SELECT文を実行する場合)
結果を返す場合には,先に説明したテーブルをまるごと取得する方法とよく似ている。まず,結果のレコードを格納するためのADODB.Recordsetオブジェクトを格納する変数をDim文で宣言する。
Dim objRec As ADODB.Recordset
そして,ADODB.ConnectionオブジェクトのExecuteメソッドを次のようにして呼び出す。
Set objRec = objCon.Execute("SELECT文",, adCmdText)
※最後の引数adCmdTextは省略することができる。
ただし,その場合,どのような指示であるのかをデータベース
プロバイダが自動評価するので,処理速度が若干低下する。
Executeメソッドを呼び出すと,指定したSELECT文が実行され,その結果がADODB.Recordsetオブジェクトとして返される。ここで取得したADODB.Recordsetオブジェクトは,読み取り専用の前方スクロールタイプカーソルである。よって,受け取った結果を書き換えてデータベースに反映させることはできない。
(b) 結果を返さない場合(SELECT文以外を実行する場合)
結果を返さない場合には,Executeメソッドの戻り値はない(より正確には,閉じたADODB.Recordsetオブジェクトが返される)。よって,次のようにしてExecuteメソッドの引数にSQL文を指定して実行するだけである。
objCon.Execute "SQL文",,adCmdText ※最後の引数adCmdTextは省略することができる。 ただし,その場合,どのような指示であるのかをデータベース プロバイダが自動評価するので,処理速度が若干低下する。
A.3.2 ADODB.Recordsetの操作
では,ADODB.ConnectionオブジェクトのExecuteメソッドを呼び出して取得したADODB.Recordsetオブジェクトの操作方法について説明しよう。取得したADODB.Recordsetオブジェクトには,結果のすべてのレコードが格納されている。
取得したADODB.Recordsetオブジェクトは,初期状態で結果の先頭のレコードを指している(指し示すレコードのことを「カレントレコード」と呼ぶ)。このレコードの特定のフィールド(項目)を取得するには,次のようにFieldsコレクションのValueプロパティを参照する。
objRec.Fields("フィールド名").Value
たとえば,結果のレコードがTable A-1のようなものであった場合,次のようにすると,“Fumitaka Osawa”という値を取得できる。
objRec.Fields("NAME").Value
もちろんこのとき,objRec.Fields("ID").Valueの値は“1”で,objRec.Fields("TEL").Valueの値は“0466-xx-xxxx”である。
なお,FieldsコレクションのValueプロパティは,Variant型である。テーブルのフィールド定義によって,どの型で値が返されるのかは異なる。
Table A-1 結果のレコードの例
ID |
NAME |
TEL |
1 |
Fumitaka Osawa |
0466-xx-xxxx |
2 |
Hitoshi Yamamoto |
03-xxxx-xxxx |
3 |
Noboru Nakamura |
045-xxx-xxxx |
結果レコードの次の行に移るには,ADODB.RecordsetオブジェクトのMoveNextメソッドを呼び出す。
objRec.MoveNext
すると,取得できる行(カレントレコード)が次の行に移動するので,objRec.Fields("NAME")とした場合,今度は2行目である“Hitoshi Yamamoto”の値が得られる。
また,MoveFirstメソッドを呼び出すと,再び先頭行に移動する。そして,MovePreviousメソッドを呼び出すと,1つまえの行に戻る。さらに,MoveLastメソッドを使えば,最後の行に移動させることができる(List A-1)。ただし,MovePreviousメソッドとMoveLastメソッドは,前方スクロールタイプカーソルのADODB.Recordsetオブジェクトに対して利用することはできない(ADODB.ConnectionオブジェクトのExecuteメソッドの呼び出しで取得したADODB.Recordsetオブジェクトは前方スクロールタイプカーソルであるため,MovePreviousメソッドおよびMoveLastメソッドは利用できない点に注意)。
List A-1 カーソルの移動に伴うカレントレコードの変化
1: 'レコードセットを先頭に移動する。
2: objRec.MoveFirst
3: MsgBox objRec.Fields("NAME").Value 'この値はFumitaka Osawaである。
4: '次の行に移動する。
5: objRec.MoveNext
6: MsgBox objRec.Fields("NAME").Value 'この値はHitoshi Yamamotoである。
7: 'まえの行に移動する。
8: objRec.MovePrevious
9: MsgBox objRec.Fields("NAME").Value 'この値はFumitaka Osawaである。
10: '最後の行に移動する。
11: objRec.MoveLast
12: MsgBox objRec.Fields("NAME").Value 'この値はNoboru Nakamuraである。
では,全レコードをループして取得したい場合の処理について説明する。まず,ADODB.Recordsetオブジェクトに含まれる全レコードの総数だが,これはADODB.RecordsetオブジェクトのRecordCountプロパティに格納される。ただし,RecordCountプロパティは前方スクロールタイプカーソルではサポートされない(-1が返される)。そのため前方スクロールタイプカーソルの場合には,ADODB.RecordsetオブジェクトのRecordCountプロパティに格納された値の分だけループ処理するというわけにはゆかない。
そこで,ADODB.RecordsetオブジェクトのEOFプロパティとBOFプロパティを利用する。EOFプロパティには,その時点で最後の行を指しているならばTrueが,そうでなければFalseが格納される。これに対してBOFプロパティは,その時点で最初の行を指しているのならばTrueが,そうでなければFalseが格納される。
EOFプロパティを使えば,List A-2のようにして全レコードを取得することができる。
List A-2 EOFプロパティを利用した全レコードの取得
1: While Not objRec.EOF
2: MsgBox objRec.Fields("NAME").Value
3: objRec.MoveNext
4: Wend
以上が,ADODB.Recordsetオブジェクトを使って,取得した結果レコードを操作する基本的な流れとなる。ADODB.Recordsetオブジェクトには,指定したフィールド順に並び替えるSortプロパティや指定した条件に満たないものを隠すFilterプロパティ,指定した条件を満たすレコードを探すFindメソッド,ADODB.Recordsetオブジェクトをファイルに保存するSaveメソッドなど,便利な機能がたくさん備わっている。これらは,必要に応じて連載中に扱ってゆく予定である。
なお,ADODB.ConnectionオブジェクトのExecuteメソッドの呼び出しで得られたADODB.Recordsetオブジェクトは,不要になった時点で解放しなければならない。解放する場合には,ADODB.RecordsetオブジェクトのCloseメソッドを呼び出して接続を閉じたのち,ADODB.Recordsetオブジェクトが格納されている変数にNothingを代入する(List A-3)。
List A-3 ADODB.Recordsetオブジェクトの解放
1: objRec.Close
2: Set objRec = Nothing
Appendix A 4/6 | ||
本文のトップへ | Appendix Aのトップへ |