先に示した『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の通りです。
|
|
|