プログラムの概要
前回に引き続き、此処では、コ ードに依るデータベースの操作 方法を学ぶ。 コネクションオブジェクトを用 いてデータベースと接続し、表 形式でデータを表示するデータ グリッドビューコントロールに レコードデータを自動的に表示 する手法を学ぶ。 既に学んだ様にコントロールを 連結する事に依り、コードレス でデータベース操作が可能で有 るが、此処では、着目して居る 行(カレントレコード)の指定と、個々の列データ(フィールドデータ)の取得に付いて学ぶ。亦、高 度なデータベース操作の下準備と仕て ADO.NET オブジェクトをコードで操作する事とデータベース 操作の基礎と成るSQL に慣れ親しむ事を目的とする。VB でアクセス操作Ⅱ
VB 2005 ④ □ ADO.NET に依るデータベース接続(コネクションオブジェクト)□ ADO.NET に依るデータベース接続(ConnectionString プロパティ、Open メソッド) □ ADO.NET に依るデータベース操作(データアダプタオブジェクト)
□ ADO.NET に依るデータベース操作(SelectCommand、CommandText プロパティ) □ ADO.NET に依るデータベース操作(Fill メソッド)
□ ADO.NET に依るデータセット操作(データセットオブジェクト)
□ ADO.NET に依るテーブルデータ操作(Tables コレクション、Clear メソッド) □ ADO.NET に依るレコードデータ操作(Rows コレクション、Count プロパティ) □ ADO.NET に依るフィールドデータ操作(Item コレクション、ToString メソッド)
□ 連結コントロールの利用(データグリッドビュー、DataSource、Datamember プロパティ) □ コネクションの切断(コネクションオブジェクト、Close メソッド) □ オブジェクト変数の開放(オブジェクト.Dispose) 今回の課題項目 □ ADO.NET に依るデータベース接続(コネクションオブジェクト) □ ADO.NET に依るデータベース操作(データアダプタオブジェクト) □ ADO.NET に依るデータセット操作(データセットオブジェクト) □ SQL 文(SELECT 文:レコードを検索する文) 今回の重点項目
■ オブジェクト・プロパティ一覧 ■ コントロールの種類 プロパティ プロパティの設定値 フォーム Name access Caption 本棚データベース ラベル1 Name lblID Text ID ラベル2 Name lblTitle Text タイトル ラベル3 Name lblPrice Text 価格 ラベル4 Name lblDate Text 購入日 ラベル5 Name lblCate Text カテゴリ ラベル6 Name lblWriter Text 著者 テキストボックス1 Name txtID テキストボックス2 Name txtTitle テキストボックス3 Name txtPrice テキストボックス4 Name txtCate テキストボックス5 Name txtWriter デートタイムピッカー Name dtpDate コンボボックス1 Name cboCate コンボボックス2 Name cboWriter データグリッドビュー Name dgvBook コマンドボタン1 Name btnInsert Text 追加 コマンドボタン2 Name btnUpdate Text 変更 コマンドボタン3 Name btnDelete Text 削除 コマンドボタン1 テキストボックス1 データグリッドビュー テキストボックス2 テキストボックス3 デートダイムピッカー コンボボックス1 コンボボックス2 テキストボックス4 テキストボックス5 コマンドボタン2 コマンドボタン3 ラベル1 ラベル2 ラベル3 ラベル4 ラベル5 ラベル6 コマンドボタン1~3は 今回は使用しない。
■ プログラムリスト ■ ' 名前空間のインポート
Imports System.Data Imports System.Data.OleDb Public Class access
' 同一クラス内でグローバルな変数の宣言 Private Cn As OleDbConnection Private Ds As DataSet
Private DaB As OleDbDataAdapter Private DaC As OleDbDataAdapter Private DaW As OleDbDataAdapter Private DaT As OleDbDataAdapter Private Tn As String = "BOOK" ' フォームが読み込まれた時の処理
Private Sub access_Load( ByVal sender As System.Object, ByVal e As System.EventArgs ) _ Handles MyBase.Load
' データベースへの接続情報の設定
Cn = New OleDbConnection( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=data.mdb" )
' データアダプタの生成
DaB = New OleDbDataAdapter( "SELECT * FROM 本", Cn )
DaC = New OleDbDataAdapter( "SELECT * FROM カテゴリ ORDER BY ID", Cn ) DaW = New OleDbDataAdapter( "SELECT * FROM 著者 ORDER BY ID", Cn ) DaT = New OleDbDataAdapter( "SELECT * FROM カテゴリ WHERE ID=0", Cn ) ' データセットの生成 Ds = New DataSet ' SQL の発行と取得したデータのデータセットへの格納 DaB.Fill( Ds, "BOOK" ) DaC.Fill( Ds, "CATEGORY" ) DaW.Fill( Ds, "WRITER" ) DaT.Fill( Ds, "TEMP" ) ' データセット内のデータソースをデータグリッドビューに連結 dgvBook.DataSource = Ds dgvBook.DataMember = "BOOK" ' コンボボックス(カテゴリ・著者)の設定 Call CboAddItem( ) End Sub ' フォームが閉じられ様と仕た時の処理
Private Sub access_FormClosing( ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.FormClosingEventArgs ) Handles MyBase.FormClosing
' 各インスタンスの破棄
Ds.Dispose( ): DaB.Dispose( ): DaC.Dispose( ): DaW.Dispose( ): DaT.Dispose( ) ' コネクションのクローズと破棄 Cn.Close( ): Cn.Dispose( ) End End Sub イベントプロシージャに其処で処 理される総てのコードを記述する のでは無く、処理ブロック毎にサ ブルーチン化する事は、開発効率 や保守性を高める効果が有る。 各テーブルから総てのフィールド のデータを抽出する SQL 文を作 成する。 Close メソッドは、関連するシス テムリソースを開放する丈で、メ モリから削除するにはDispose す る必要が有る。 記述を簡略化する為に、名前空間 をインポートして居る。此れに依 り、名前空間以下のクラスは、名 前空間を省略して記述出来る。 此処で宣言した変数は、同じクラ ス内の総てのプロシージャ(メソ ッド)で値の参照と設定を行う事 が出来る。 ORDER BY 節は抽出データの並 び順を、WHERE 節は、抽出条件 を設定する。
' データグリッドビューの行ヘッダがクリックされた時の処理
Private Sub dgvBook_RowHeaderMouseClick( ByVal sender As System.Object, _ ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs ) _ Handles dgvBook.RowHeaderMouseClick Dim S As String = "" ' 着目行の各フィールド値をテキストボックスに表示 Dim N As Integer = dgvBook.CurrentRow.Index If N < Ds.Tables( "BOOK" ).Rows.Count Then ' データセットから取得
txtID.Text = Ds.Tables( "BOOK" ).Rows( N ).Item( "ID" ).ToString
txtTitle.Text = Ds.Tables( "BOOK" ).Rows( N ).Item( "タイトル" ).ToString txtPrice.Text = Ds.Tables( "BOOK" ).Rows( N ).Item( "価格" ).ToString dtpDate.Value = Ds.Tables( "BOOK" ).Rows( N ).Item( "購入日" ).ToString txtCate.Text = Ds.Tables( "BOOK" ).Rows( N ).Item( "カテゴリ ID" ).ToString txtWriter.Text = Ds.Tables( "BOOK" ).Rows( N ).Item( "著者 ID" ).ToString
' データグリッドビューから取得(参考)
' txtID.Text = dgvBook.CurrentRow.Cells( "ID" ).Value
' txtTitle.Text = dgvBook.CurrentRow.Cells( "タイトル" ).Value ' txtPrice.Text = dgvBook.CurrentRow.Cells( "価格" ).Value ' txtDate.Text = dgvBook.CurrentRow.Cells( "購入日" ).Value ' txtCate.Text = dgvBook.CurrentRow.Cells( "カテゴリ ID" ).Value ' txtWriter.Text = dgvBook.CurrentRow.Cells( "著者 ID" ).Value
' コンボボックス(カテゴリ)の設定 Ds.Tables( "TEMP" ).Clear( )
S = Ds.Tables( "BOOK" ).Rows( N ).Item( "カテゴリ ID" ).ToString DaT.SelectCommand.CommandText = _
"SELECT カテゴリ名 FROM カテゴリ WHERE ID=" & S DaT.Fill( Ds, "TEMP" )
S = Ds.Tables( "TEMP" ).Rows( 0 ).Item( "カテゴリ名" ).ToString For I As Integer = 0 To ( cboCate.Items.Count - 1 ) If cboCate.Items.Item( I ) = S Then cboCate.SelectedIndex = I Exit For End If Next ' コンボボックス(著者)の設定 Ds.Tables( "TEMP" ).Clear( )
S = Ds.Tables( "BOOK" ).Rows( N ).Item( "著者 ID" ).ToString DaT.SelectCommand.CommandText = _
"SELECT 著者名 FROM 著者 WHERE ID=" & S DaT.Fill( Ds, "TEMP" )
S = Ds.Tables( "TEMP" ).Rows( 0 ).Item( "著者名" ).ToString For I As Integer = 0 To ( cboWriter.Items.Count - 1 ) If cboWriter.Items.Item( I ) = S Then cboWriter.SelectedIndex = I Exit For End If Next Else
txtID.Text = "": txtTitle.Text = "": txtPrice.Text = "": dtpDate.Text = "": txtCate.Text = "" txtWriter.Text = "": cboCate.SelectedIndex = -1: cboCate.SelectedIndex = -1
End If End Sub フィールドデータが、ヌルやオブ ジェクトの場合が有る為、VB で 取り扱う事の出来る文字列に変更 する為に、ToString を使用する。 此処で宣言した変数は宣言したサ ブプロシージャ内でしか値の参照 と設定を行う事が出来ない。 For 文等のブロック内で宣言した 変数は、宣言したブロック内でし か値の参照と設定を行う事が出来 ない(変数I が相当)。 記号アンパサント(&)は、文字 列を結合する演算子で有る。 コンボボックスの項目をコードで 選択するには、SelectedIndex に 選択する項目のインデックスを設 定する。 左記の様に、データグ リッドビューから指定 行の列データを取得す る事も出来る。此の様 に、コードの記述方法 は、必ずしも一通りで は無い。
' コンボボックスにアイテムを追加するジェネラルプロシージャ Private Sub CboAddItem( )
' カテゴリの設定 cboCate.Items.Clear( )
For I As Integer = 0 To ( Ds.Tables("CATEGORY").Rows.Count - 1 )
cboCate.Items.Add( Ds.Tables( "CATEGORY" ).Rows( I ).Item( "カテゴリ名" ).ToString ) Next
' 著者の設定
cboWriter.Items.Clear( )
For I As Integer = 0 To ( Ds.Tables("WRITER").Rows.Count - 1 )
cboWriter.Items.Add( Ds.Tables( "WRITER" ).Rows( I ).Item( "著者名" ).ToString ) Next End Sub End Class コンボボックス(ComboBox) コンボボックスコントロールは、テキストボックス(TextBox)コントロールとリストボックス (ListBox)コントロールの機能を組み合わせた物で、ユーザーは、テキストボックス部分にテキス トを直接入力する方法と、リスト部分から項目を選択する方法の孰れでも入力する事が出来るが、 一般的に、折り畳む事の出来るリストボックスと仕て利用する事が多い。リスト部分の主要なコレ クション、メソッド、プロパティには、下記の物が有る。 SelectedIndex:現在選択されて居る項目のインデックスを設定・取得するプロパティ Items:項目のオブジェクトを取得するコレクション Items.Count:現在の項目数を返すプロパティ Items.Clear:項目をクリアするメソッド Items.Add:新しい項目を追加するメソッド Items.Remove:項目を削除するメソッド Items.Item:指定したインデックスに有る項目を取得するプロパティ Count は、個数を表すプロパティ で有り、1 スタートで有る。 Rows の引数は、インデックスを 表すプロパティで有り、0 スター トで有る。 デートタイムピッカー(DateTimePicker) デートタイムピッカーコントロールは、日付や時間のリストから1 つの項目を選択する為のコント ロールで有る。此のコントロールで日付を表す場合、テキスト表示された日付のドロップダウンリ ストと、其の隣の下向きの矢印をクリックした時に表示されるグリッドの2 箇所の部分で構成され る。主要なプロパティには、下記の物が有る。 Value:代入された日付や時刻値を設定・取得するプロパティ Text:書式の設定された Value プロパティの値を示すプロパティ Format:表示される日時の書式を設定・取得するプロパティ CustomFormat:日付や時刻のカスタム書式指定文字列を取得・設定するプロパティ MaxDate:選択出来る日時の最大値を取得・設定するプロパティ MinDate:選択出来る日時の最小値を取得・設定するプロパティ
OleDbConnection クラス データソースへの開いた接続を表すクラス OleDbConnection オブジェクトは、データソースへの一意な接続を表す。サーバーとクライ アントで構成されるデータベースシステムでは、サーバーへのネットワーク接続に相当する。 OleDbConnection オブジェクトは、適用範囲外に抜けても、自動的に閉じられる事は無い。即ち、例え ば、プロシージャレベルで宣言した変数に割り当てられた OleDbConnection オブジェクトを開いた場 合、其のプロシージャを抜けても、自動的に閉じられる事も、オブジェクト自体がメモリから開放され る事は無い。其の為、Close メソッドや Dispose メソッドを呼び出すか、OleDbConnection オブジェク トをUsing ステートメント内に記述する事に依り、明示的に接続を閉じる必要が有る。
OleDbConnection クラスのコンストラクタ
OleDbConnection オブジェクトを生成するメソッド
Dim 変数 As New OleDbConnection( 接続文字列 )
接続文字列を指定して、OleDbConnection クラスの新しいインスタンスを初期化する。
引数の接続文字列には、データベースを開く為に使用する接続を表す文字列を指定する。ACCESS デ ータベースを接続する為の接続文字列は、下記の様に成る。
例1:"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=data.mdb"
例2:"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:¥access_db¥data.mdb"
上記の例1では、プロバイダにMicrosoft.Jet.OLEDB.4.0(Access 2000 以降用)を、データソース(接 続対象と成るデータベース)にEXE ファイルと同じフォルダに格納された data.mdb を指定して居る。 猶、接続対象と成るデータベースがEXE ファイルと同じフォルダに格納されて居ない場合は、例 2 の 様に、フルパスで指定する必要が有る。
猶、セキュリティ情報に関して、Persist Security Info や Integrated Security も指定する事も出来る。
OleDbConnection クラスの新しいインスタンスを作成すると、読み書き可能プロパティは、引数の接続 文字列のキーワードを関連付けて設定した場合を除いて、下記の初期値に設定される。 プロパティ 初期値 ConnectionString 引数で指定した接続文字列 ConnectionTimeout 15 Database 空の文字列( "" ) DataSource 空の文字列( "" ) 猶、此等のプロパティの値を変更するには、ConnectionString プロパティを使用する必要が有る。 OleDbConnection クラスのコンストラクタには、引数を指定しない形のオーバーロードも有る。此のコ ンストラクタを使用した場合は、インスタンスを生成した後、ConnectionString プロパティで、プロバ イダやデータソースを指定する必要が有る。 機 能 書 式 解 説 機 能 解 説
OleDbConnection クラスの Open メソッド (参考) ConnectionString で指定したプロパティ設定を使用してデータベース接続を開くメソッド
Object.Open( )
接続プール内で開いて居る接続が利用出来る場合は、其の接続を使用し、利用出来ない場合 は、データソースへの新しい接続を確立する。
OleDbConnection は、適用範囲外でも自動的に閉じられる事はない。其の為、Close や Dispose を呼び 出すか、接続をUsing ステートメント内に記述して、使用後は、明示的に接続を閉じる必要が有る。 OleDbConnection クラスの Close メソッド データソースへの接続を閉じるメソッド Object.Close( ) 保留中のトランザクションをロールバックし、其の後、接続を接続プールに解放する。接続 プールが無効の場合は、接続を閉じる。
StateChange イベントの処理中に Close メソッドを呼び出しても、更に StateChange イベントが発生 する事は無い(イベントの連鎖は無い)。亦、プログラム中で、複数回 Close メソッドを呼び出しても 例外(エラー)は発生しない。 Close メソッドは、関連するシステムリソースを開放する丈で、オブジェクトをメモリから削除する訳 では無い。メモリから削除するには、Dispose メソッドを実行する必要が有る。 機 能 書 式 解 説 機 能 書 式 解 説
DataAdapter に依る Connection の Open と Close
DataAdapter クラスの Fill メソッドを使用してデータベースより DataSet オブジェクトに行を取得 する場合、及び、Update メソッドを使用して DataSet オブジェクトに加えられた変更をデータベ ースに書き戻す場合には、Connection の開始と終了を明示的に行う必要は無い。
Fill メソッドは、接続が未だ開いて居ない事を認識すると DataAdapter が使用して居る Connection を暗黙的に開く。Fill が接続を開いた場合は、Fill の終了時に Fill が接続を終了する。此れは、マ ニュアルには記載されて居ないが、Update メソッドの場合も、同様で有る。
猶、Fill を呼び出す前に接続が開いて居た場合は、接続は開いた儘に成る。此れに依り、Fill や Update 等の単一の操作を扱う場合にコードを簡略化出来る。 此れに対し、開いて居る接続を必要とする複数の操作を実行する場合は、Connection の Open メソ ッドを明示的に呼び出し、データソースに対する操作の実行後にConnection の Close メソッドを呼 び出す事でアプリケーションのパフォーマンスを改善出来る。リソースを解放して他のクライアン トアプリケーションが使用出来る様にする為に、データソースへの接続を開いた儘にする時間は最 小限にする事を推奨する。
OleDbConnection クラスの ConnectionString プロパティ (参考) データベースを開く為に使用する文字列を取得・設定するプロパティ Object.ConnectionString = 接続文字列 データソース名を含むOLE DB プロバイダ接続文字列、及び、初期接続を確立する為に必 要な其の他のパラメータを指定する。 接続文字列の書式は、OLE DB 接続文字列の書式と粗一致して居るが、下記の相違点が有る。 ・Provider 句は必須で有る。指定出来るプロバイダには、Microsoft.Jet.OLEDB.4.0(Access 2000 以 降)、SQLOLEDB(SQL Server 6.0 以前)、MSDAORA(Oracle 8.1.7 未満)等が有る。
・ODBC や ADO とは異なり、Persist Security Info を false(既定値)に設定すると、ユーザーが設定 した接続文字列からセキュリティ情報を除いた接続文字列が返される。Persist Security Info キーワ ードをtrue に設定した場合(非推奨)を除き、OleDbConnection では、接続文字列のパスワードは 永続化されず、返されない。高度なセキュリティレベルを維持する為には、Persist Security Info を false に設定して、Integrated Security キーワードを使用する事が推奨されて居る。
接続文字列の例を、下記に示す。
"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:¥bin¥LocalAccess40.mdb" "Provider=SQLOLEDB;Data Source=(local);Integrated Security=SSPI"
"Provider=MSDAORA; Data Source=ORACLE8i7;Persist Security Info=False;Integrated Security=Yes"
接続文字列中にData Source キーワードを指定しない場合、プロバイダは、利用可能なローカルサーバ への接続を試みる。 ConnectionString プロパティを設定出来るのは、接続が閉じて居る時丈で有る。接続文字列値の多くに は、対応する読み取り専用プロパティが有る。接続文字列を設定すると、エラーが検出された場合を除 いて、此等のプロパティが更新される。エラーが発生した場合は、孰れのプロパティも更新されない。 OleDbConnection プロパティは、ConnectionString に含まれて居る設定丈を返す。 閉じた接続に対して ConnectionString をリセットすると、総ての接続文字列値と関連プロパティがリ セットされる(パスワードも対象と成る)。例えば、Initial Catalog= AdventureWorks を指定した接続 文字列を設定した後で、此の接続文字列を下記の様ににリセットすると、Database プロパティは AdventureWorks に設定されない(接続文字列の Initial Catalog 値は、Database プロパティに対応す る)。
Provider= SQLOLEDB;Data Source= MySQLServer;IntegratedSecurity=SSPI
プロパティの設定時には、接続文字列に対して予備的な検証が実行される。Provider、Connect Timeout、 Persist Security Info、OLE DB Services の値が文字列に含まれて居る場合は、此等の値がチェックさ れる。アプリケーションがOpen メソッドを呼び出した時は、接続文字列が完全に検証される。接続文 字列に無効なプロパティやサポートされないプロパティが含まれて居る場合は、ArgumentException 等の実行時例外が発生する。 機 能 書 式 解 説
OleDbDataAdapter クラス データソースとデータセットの間を仲介するクラス データセットへのデータの格納とデータソースの更新に使用される一連のデータコマンド とデータベース接続を表す。 DataAdapter は、DataSet とデータソースとの間でデータの取得と保存を行う為の、仲介の役割を果た す。DataAdapter は、其の為に、DataSet 内のデータをデータソース内のデータと一致する様に変更す る Fill メソッドと、データソース内のデータを DataSet 内のデータと一致する様に変更する Update メソッドが用意されて居る。
OLE DB をサポートするデータソース(Access 等)に接続する場合は、関連付けられた OleDbCommand オブジェクトやOleDbConnection オブジェクトと共に OleDbDataAdapter を使用する事に依り、全体 的なパフォーマンスを向上させる事が出来る。 データベースの種類 最適化されたクラス OLE DB データソース OleDbCommand、OleDbConnection、OleDbDataAdapter SQL Server データベース SqlCommand、SqlConnection、SqlDataAdapter ODBC データソース OdbcCommand、OdbcConnection、OdbcDataAdapter Oracle データベース OracleCommand、OracleConnection、OracleDataAdapter DataAdapter のインスタンスを作成すると、読み書き可能プロパティが初期値に設定される。此等の初 期値の一覧に付いては、DataAdapter コンストラクタの記述を参照され度い。 OleDbDataAdapter クラスのコンストラクタ OleDbDataAdapter オブジェクトを生成するメソッド
Dim 変数 As New OleDbDataAdapter( 選択クエリ, 接続 )
SelectCommand クラスの CommandText プロパティを使用して、OleDbDataAdapter クラ スの新しいインスタンスを初期化する(4 種のオーバーロードが有る)。 引数の選択クエリには、SQL SELECT ステートメント、又は、ストアドプロシージャで有る文字列を 指定する。此の文字列は、OleDbDataAdapter の SelectCommand プロパティに使用される。 亦、引 数の接続には、接続を表す OleDbConnection を指定する。 OleDbDataAdapter の実装では、OleDbConnection が開いて居ない場合は、此の接続が開かれ、再び 閉じられる。此れは、アプリケーションで複数のOleDbDataAdapter オブジェクトの Fill メソッドを 呼び出す必要が有る場合に効果的で有る。OleDbConnection が既に開いて居る場合、其の接続を閉じる には、明示的にClose メソッドや Dispose メソッドを呼び出す必要が有る。 OleDbDataAdapter のインスタンスを作成すると、下記の様に読み取り/書き込みプロパティが初期値 に設定される。 プロパティ 初期値 MissingMappingAction MissingMappingAction.Passthrough MissingSchemaAction MissingSchemaAction.Add 機 能 解 説 機 能 書 式 解 説
OleDbDataAdapter クラスの Fill メソッド データをDataSet に取り込むメソッド
Object.Fill( データセット名, テーブル名 )
DataSet 名と DataTable 名を使用して、データソース内の列と一致する様に DataSet 内の 行を追加・更新する(7 種のオーバーロードが有る)。 引数のデータセット名には、レコード、及び、必要に応じてスキーマを格納する為のDataSet を指定す る。亦、引数のテーブル名には、テーブルマップに使用するソーステーブルの名前を指定する。 亦、戻り値には、DataSet で正常に追加や更新された行数が返される。此れには、行を返さないステー トメントの影響を受ける行は含まれない。コマンドが行を返さない場合は、DataSet にテーブルは追加 されない(此の場合、例外は発生しない)。
Fill メソッドは、SELECT ステートメントを使用して、データソースからデータを取得する。SELECT コマンドに関連付けられた IDbConnection オブジェクトは、有効な物で有る必要が有るが、開いて居 る必要は無い。Fill メソッドを呼び出す前に IDbConnection が閉じて居る場合は、接続が開かれ、デ ータを取得した後で再び閉じられる。Fill メソッドを呼び出す前に接続が開いて居た場合は、接続は開 いた儘に成る。 DataTable へのデータの格納中に重複する列が存在する場合、2 番目以降の列には、DbDataAdapter オブジェクトに依り、自動的にcolumnname1、columnname2、columnname3 の様な形式で名前が付 けられ、亦、受信したデータに無名の列が含まれて居た場合は、Column1、Column2 の様な形式の名 前でDataSet に列が格納される。 指定したクエリが複数の結果を返す場合は、各結果セットが個別のテーブルに格納される。2 番目以降 の結果セットには、指定されたテーブル名に整数値を追加した名前が付けられる。例えば、Table、Table1、 Table2 の様に成る。行を返さないクエリではテーブルは作成されない。従って、挿入クエリの後で選択 クエリを処理した場合、選択クエリで作成されるテーブルが最初に作成されるテーブルに成る為、此の テーブルがTable と謂う名前に成る。アプリケーションで列名やテーブル名を使用する時は、此等の名 前付けパターンとの衝突が発生しない様に注意する必要が有る。
Fill メソッドは、大文字と小文字の違いを除いて名前が一致する DataTable オブジェクトが DataSet 内に複数含まれる場合に、其等を区別する。此の場合、Fill メソッドは、大文字と小文字を区別して比 較を実行し、対応するテーブルを見付ける。正確に一致するテーブルが存在しない場合は、新しく作成 する。此の動作を表すコード例を、下記に示す。
Dim Ds As DataSet = new DataSet( ) Ds.Tables.Add("aaa")
Ds.Tables.Add("AAA")
Adapter.Fill( Ds, "aaa" ) ' 既に DataSet 内に存在する "aaa" に充填する。 Adapter.Fill( Ds, "Aaa" ) ' 新しい "Aaa" と謂う名前のテーブルを追加する。
猶、ActiveX データオブジェクト(ADO)と ADO.NET 間のリンクを行う為に、下記のオーバーロー ドも用意されて居る。
OleDbDataAdapter.Fill (DataTable, Object)、OleDbDataAdapter.Fill (DataSet, Object, String) 機 能
書 式
OleDbDataAdapter クラスの SelectCommand プロパティ 選択クエリの取得と設定を行うプロパティ
Object.SelectCommand = OleDbCommand
データソース内のレコードを選択する為の SQL ステートメント、又は、ストアドプロシー ジャの取得と設定を行う。
引数のOleDbCommand には、Fill 処理中に、DataSet に格納するレコードをデータソースから選択す る為のOleDbCommand オブジェクトを指定する。
作成済みのOleDbCommand に SelectCommand が割り当てられた場合、OleDbCommand のクローン は作成されない。SelectCommand に依り、作成済みの OleDbCommand オブジェクトへの参照が維持 される。 OleDbCommand クラスの CommandText プロパティ クエリの取得と設定を行うプロパティ Object.CommandText = クエリ データソースで実行するSQL ステートメントやストアドプロシージャの取得と設定を行う。 引数のクエリには、実行する SQL ステートメント、又は、ストアドプロシージャを指定する(既定値 は空の文字列)。 CommandType プロパティの値に依り、CommandType プロパティに設定する文字列の種類を、下記 に示す。 CommandType プロパティ CommandType プロパティ StoredProcedure ストアドプロシージャ名 ※1 TableDirect テーブル名 ※2 Text SQL ステートメント ※3 ※1 ストアドプロシージャ名に特殊文字が含まれる場合、エスケープ文字の構文を使用する必要が有 る。孰れかのExecute メソッドを呼び出すと、コマンドが此のストアドプロシージャを実行する。 ※2 テーブル名に特殊文字が含まれる場合は、エスケープ文字の構文を使用する必要が有る。孰れか のExecute メソッドを呼び出すと、指定したテーブルの総ての行と列が返される。
※3 OLE DB.NET プロバイダでは、OleDbCommand が呼び出す SQL ステートメントやストアドプ ロシージャにパラメータを渡す為の名前付きパラメータは利用出来ない。此の場合は、疑問符プ レースホルダを使用する。次に例を示す。
SELECT * FROM 本 WHERE ID = ?
従って、パラメータの疑問符プレースホルダの位置と、OleDbParameter オブジェクトを OleDbParameterCollection に追加する順序とを、正しく対応させる必要が有る。 現在の接続で実行、又は、フェッチ操作が実行中の場合は、CommandText プロパティは設定出来ない。 機 能 書 式 解 説 機 能 書 式 解 説
DataSet オブジェクト・1 データのメモリ内キャッシュを表すクラス データソースから取得されたデータをメモリ内にキャッシュする。 DataSet オブジェクトは、ADO.NET で非接続型分散データシナリオをサポートする上で中心的な役割 を果たすクラスで有る。DataSet はメモリ内に常駐するデータ表現で有り、データソースの違いに拘ら ず、一貫性の有るリレーショナルプログラミングモデルを提供する。複数の異なるデータソースやXML データと組み合わせて使用する事が出来、亦、アプリケーションに取ってローカルなデータの管理にも 使用する事が出来る。DataSet は、関連テーブル、制約、及び、テーブル間のリレーションシップを含 む、完全なデータセットを表現する。DataSet オブジェクトモデルを、下図に示す。
DataSet は、DataRelation オブジェクトと相互に関連付ける事が出来る DataTable オブジェクトのコ レクションで構成される。UniqueConstraint オブジェクトと ForeignKeyConstraint オブジェクトを 使用して、DataSet 内でデータの整合性を適用する事も出来る。 DataTable オブジェクトにはデータを格納出来るのに対して、DataRelationCollection を使用するとテ ーブルの階層構造内を移動出来る。テーブルは、Tables プロパティを使用してアクセス出来る DataTableCollection に格納される。DataTable オブジェクトにアクセスする時は、条件付きで大文字 と 小 文 字 が 区 別 さ れ る 事 に 注 意 さ れ 度 い 。 例 え ば 、mydatatable と謂う名 前の DataTable と Mydatatable と謂う名前のテーブルが有る場合は、此の 2 つのーブルの孰れかを検索する文字列は大文 字と小文字を区別すると看做される。但し、mydatatable と謂う名前は存在するが Mydatatable と謂 う名前が存在しない場合は、検索文字列は大文字と小文字を区別しないと看做される。 DataSet では、データとスキーマを XML ドキュメントとして読み取ったり、書き込んだり出来る。読 み込んだデータとスキーマは、HTTP で転送出来、XML 対応の総てのプラットフォーム、及び、アプ リケーションで使用出来る。スキーマをXML スキーマと仕て保存するには WriteXmlSchema メソッ ドを使用する。スキーマとデータの両方を保存するにはWriteXml メソッドを使用する。スキーマとデ ータの両方を含むXML ドキュメントを読み取るには、ReadXml メソッドを使用する。 機 能 解 説
データソースからデータを取得して、DataSet オブジェクトに充填するには、通常、DataAdapter クラ スのFill メソッドを使用する。
Fill メソッドを呼び出して DataSet オブジェクトに充填した時、下図の様に、DataSet オブジェクト、 DataTable オブジェクト、DataRow オブジェクトが階層化される。
テーブルの指定
DataTable オブジェクトは、DataSet 内に充填されたテーブルを表し、DataSet オブジェクトの Tables コレクションから取得する事が出来る。
例:テーブル名がBOOK のテーブルを指定する。 Ds.Tables("BOOK")
レコード(行)の指定
DataRow オブジェクトは、DataSet 内に充填されたテーブルに含まれるレコードを表し、DataSet オ ブジェクト内のDataTable オブジェクトの Rows コレクションから取得する事が出来る。 例:テーブル名がBOOK のテーブルの最初のレコードを指定する。 Ds.Tables("BOOK").Rows(0) フィールド(列)の指定 指定レコード内のフィールドは、Item プロパティから取得する事が出来る。Item プロパティは、フィ ールドの値をObject 型で返すプロパティで有る。 例:テーブル名がBOOK のテーブルの最初のレコードの ID フィールドを指定する。 Ds.Tables("BOOK").Rows(0).Item("ID") 猶、フィールド値がNull 値か何うかを調べる場合は、下記の様に、IsNull プロパティを使用する。 If Ds.Tables("BOOK").Rows(0).IsNull("ID") Then ' 値が Null 値の場合の処理 End If
DataSet 内のテーブル名とフィールド名
Rows コレクション内の特定の DataRow オブジェクトを指定するには、0 から始まる序数を使用するが、 Tables コレクション内の特定の DataTable オブジェクトを指定する場合や、DataRow オブジェクト内 の特定の Item プロパティを指定する場合には、0 から始まる序数以外に、テーブル名やフィールド名 で指定する事が出来る。 テーブル名とフィールド名は、DataAdapter オブジェクトの TableMappings プロパティで決まる。明 示的にTblaMappings プロパティを設定しなかった場合は、フィールド名は、クエリに含まれるフィー ルド名に合致する様に自動的に設定されるが、テーブル名は、既定値で TableN(N は連番)と成る。 其の為、任意のテーブル名を指定し度い時は、Fill メソッドを呼び出す時に、DataSet オブジェクトの Tables コレクションと仕て格納し度いテーブル名を第 2 引数に指定する。 例:DataSet オブジェクト内のテーブル名を BOOK に指定して読み込む。 Dim DaB As OleDbDataAdapter
DaB = New OleDbDataAdapter("SELECT * FROM 本", Cn) DaB.Fill(Ds, "BOOK") DataTable クラスの Clear メソッド DataTable から総てのデータを消去するメソッド Object.Clear( ) テーブルから総てのレコード(行)が削除される。 子レコードを孤立させる様な子リレーションシップが適用されて居る場合は、例外が発生する。 データセット内の特定のテーブルをクリアするには、下記の様に記述する。 データセット名.Tables("テーブル名").Clear DataRowCollection クラスの Count プロパティ レコード数を表す値を取得するプロパティ Object.Count DataRowCollection コレクション内の DataRow オブジェクトの合計数を取得する。 データセット内の特定のテーブルのレコード数を取得するには、下記の様に記述する。 データセット名.Tables("テーブル名").Rows.Count ※ データベース操作に於いて、通常、1 件分のデータをレコード、1 レコードに含まれる個々のデータ をフィールドと呼ぶが、レコードを行(Row)、フィールドを列(Column)と謂う事も多い。書籍 等では、孰れの呼称も使用されて居るので、不要な誤解を招かない為にも、両者が同じ物を表して 居る事を認識して置いた方が良い。 機 能 書 式 解 説 機 能 書 式 解 説