データベース千夜一夜第13回

プログラミングとSQL(1)
~ADO.NETによるデータベース制御の基礎
長谷川裕行
有限会社 手國堂

サンプル(1)~ex01

先に示した『1.ユーザーの入力した「商品ID」をキーに「商品_mr」テーブルからレコードを抽出し、品名と販売単価を表示する』という仕様のアプリケーションを作ってみましょう。


- フォームのデザイン -

まずフォームを作ります。フォームは図1のようなデザインです。

テキストボックス“txtItemId”に商品IDを入力してコマンドボタン“btnSearch”をクリックすると、テーブル「商品_mr」から該当するレコードを抽出し、「品名」フィールドの値をラベル“lblItemName”に、「販売単価」フィールドの値をラベル“UnitPrice”に表示します。



- アプリケーションの構造 -

ここでは、SQL Serverの接続向けに設計されたオブジェクトSqlConnection、SqlCommand、SqlDataReaderを使います。

まず、SqlClientライブラリを取り込んでおきます。このコードは、すべてのコードの先頭に記述します。

  Imports System.Data.SqlClient

コマンドボタン“btnSearch”のClickイベントを処理するSubプロシージャ“btnSearch_Click”でSQLの設定を行い、実際の処理はSubプロシージャ“Search”に委ねます。

以下、それぞれのコードを順に説明します。


- btnSearch_Click~コマンドボタン“btnSearch”の
Clickイベントを処理 -

SQLを格納する文字列を“strSql”というString型の変数で宣言し、WHERE句に与える条件式のキーワード部分だけを省いたSQL文字列を代入します。

  Dim strSql As String
  strSql = "SELECT 商品ID, 品名, 販売単価 FROM 商品_mr WHERE 商品ID = "

ここで設定するSQLは“商品ID = ”までで、これにテキストボックス“txtItemId”に入力された「商品ID」を連結して最終的なSQLとします。

コマンドボタン“cmdSearch”がクリックされた時点でテキストボックス“txtItemId”に値が入力されていなければ、エラーメッセージを表示して処理を終えます。

  If txtItemId.Text = "" Then
   MessageBox.Show("商品IDを入力してください。", _
   "入力エラー", MessageBoxButtons.OK)

何らかの文字列が入力されていれば、実際にSQLを処理する下請けプロシージャ“Search”を呼び出します。その直前に、SQL文字列“strSql”にテキストボックス“txtItemId”に入力された「商品ID」を連結し、引数として“Search”に渡します。

  Else ' パラメータを付け足して検索を実行
   strSql = strSql & txtItemId.Text
   Search(strSql)
  End If


- Search(1)~オブジェクト変数の宣言 -

プロシージャ“Search”はSQL文字列を引数に受け取り、実際にデータベースを制御してその結果を表示します。“btnSearch”プロシージャから呼び出されるときSQL文字列を受け取るため、このプロシージャの宣言は以下のようになります。

  Private Sub Search(ByVal strSql As String)

プロシージャ内で処理結果をラベルに表示するため、戻り値を持たないSubプロシージャとします。

まず、データベースを扱うためのオブジェクトを宣言しておきます。

  Dim objConnect As New SqlConnection
  Dim objCommand As New SqlCommand
  Dim objDataReader As SqlDataReader

SqlConnectionとSqlCommandはNewを使って宣言時にインスタンスを生成しますが、SqlDataReaderはSqlCommandオブジェクトのExecuteReaderメソッドの戻り値としてインスタンスを受け取るため、変数の宣言のみとします。


- Search(2)~データベースの接続 -

これ以降、Try~End Tryループの中で実際にデータベースを開いてSQLを発行し、処理結果をラベルに表示します。

sqlConnectionのConnectionStringに接続文字列を設定します。接続文字列が長いので折り返し表示されていますが、" "内は実際には1行の文字列です。もちろん、文字列連結演算子&を使って、複数行に分割して記述しても構いません。

  objConnect.ConnectionString = _
  "Persist Security Info=False;Integrated Security=SSPI;database=db1001ya;server=localhost"

接続文字列では、“database=db1001ya”としてデータベース名を指定しています。ここを書き換えれば、異なるデータベースを指定できます。“server=localhost”という記述は、SQL Serverが開発用のコンピュータ上で稼働しているためです。ネットワーク上のリモート・コンピュータで稼働している場合は、そのコンピュータ名を記述します。

 こうして接続文字列を設定したsqlConnectionオブジェクトを、sqlCommandのConnectionプロパティに設定します。

  objCommand.Connection = objConnect

これで、sqlConnectionのOpenメソッドを実行すれば、データベースに接続できます。

  objConnect.Open()


- Search(3)~SQLの発行 -

続いてsqlCommandのCommandTextプロパティにSQL文字列(このプロシージャの引数として受け取った“strSql”)を代入します。

  objCommand.CommandText = strSql

これで、CommandのExecuteReaderメソッドを実行すれば、データベースに対して設定したSQLが発行され、その結果セットがsqlDataReader型オブジェクトへの参照として返ってきます。これを、先に宣言していたsqlDataReader型の変数objDataReaderに受け取ります。

この処理では常に該当する1件のレコードしか受け取らないため、CommandのExecuteReaderメソッドで引数に“CommandBehavior.SingleRow”を指定しておきます。

  objDataReader = objCommand.ExecuteReader(CommandBehavior.SingleRow)


- Search(4)~処理結果の表示 -

SQLが正しく処理されれば、objDataReaderを通してデータセットを保持するsqlDataReaderオブジェクトにアクセスできます。

Readメソッドを発行すると、結果セットの先頭行を読み取れるようになります。先にCommandのExecuteReaderメソッドで“CommandBehavior.SingleRow”を指定し1行のみ保持するよう設定したので、もしこのとき該当するレコードが1件もなければ、ReadメソッドはFalseを返してきます。そうでなければ(該当レコードが存在すれば)Trueが返ります。

そこで、ReadメソッドがTrueならレコード内のフィールドの値を読み取ってラベルに表示し、そうでなければ(Falseなら)エラーメッセージを表示して処理を終えます。

  If objDataReader.Read() = True Then
   lblItemName.Text = objDataReader("品名")
   lblUnitPrice.Text = objDataReader("販売単価")
  Else -------- 該当するレコードが存在しない場合
   MessageBox.Show( _
   "該当する商品が見つかりません。", "検索エラー", MessageBoxButtons.OK)
  End If

sqlDataReaderのReadメソッドを呼び出すと、フィールド名を指定してその値を取り出せるようになります。検索成功時の以下の2行で、フィールドの値をラベルのTextプロパティに代入して表示させています。

   lblItemName.Text = objDataReader("品名")
   lblUnitPrice.Text = objDataReader("販売単価")


- Search(5)~例外処理と後始末 -

これ以降は、データベース制御時の例外処理と、オブジェクトを閉じる後始末です。

例外処理では、エラー時にExceptionオブジェクトのエラーメッセージを表示するだけにしています。

  Catch objExcept As Exception ' 例外処理
   MessageBox.Show(objExcept.ToString, "DBエラー", MessageBoxButtons.OK)

後始末では、sqlDataReaderとsqlConnectionのCloseメソッドを呼び出し、これらを閉じておきます。Connectionオブジェクトの接続を閉じることは当然なのですが、結果セットを保持しているDataReaderオブジェクトも閉じるということはつい忘れがちなので、以下のコードはパターンとして覚えておきましょう。

  Finally
   If Not objDataReader Is Nothing Then
    objDataReader.Close()
   End If
   If Not objConnect Is Nothing Then
    objConnect.Close()
   End If

完成したアプリケーションは図2のようになります。

また、ソースコードはリスト1の通りです。


図2:完成したアプリケーションex01.exe
リスト1:ex01のソースコード




トップページ
最も基本的な関連付け
サンプル(1)~ex01
フォームのデザイン
アプリケーションの構造
btnSearch_Click~コマンドボタン“btnSearch”のClickイベントを処理
Search(1)~オブジェクト変数の宣言
Search(2)~データベースの接続
Search(3)~SQLの発行
Search(4)~処理結果の表示
Search(5)~例外処理と後始末
サンプル(2)~ex02
あとがき
Copyright © MESCIUS inc. All rights reserved.