この特集のトップページへ
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

prev Appendix A 4/6 next
本文のトップへ | Appendix Aのトップへ