ここで、レコードの削除を取り消す例を紹介しておきましょう。本コラムの第14回「プログラミングとSQL(2)~レコードの削除処理」で紹介した、商品マスターからの商品検索と削除処理に手を加え、[削除]ボタンをクリックしてDELETE命令で商品のレコードを削除した後、その処理を取り消すこともできる──という仕様に変更したものです。
【注意】
本コラムのサンプルでは、MSDEを使った個人的なデスクトップ環境でデータベースを扱うことを前提にしているため、接続先のSQL Serverは“localhost”としています。
ネットワーク上のリモート・コンピュータで稼働しているSQL Serverに接続する場合には、以下の接続文字列の最後の引数“server=localhost”の“localhost”の箇所を適宜サーバー名に書き換えてください(ここで言う「サーバー名」とはコンピュータの識別名ではなく、SQL Serverに割り当てた識別名です)。
objConnect.ConnectionString = _
"Persist Security Info=False;
Integrated Security=SSPI;database=db1001ya;
server=localhost"
~~~~~~~~~
↑この箇所を書き換える
- 削除後に取り消せる -
アプリケーションの動作は次のようになります(画面1~画面5)。
(1)テキストボックスに商品IDを入力して[検索]ボタンをクリック
(2)該当する商品の品名が表示されるので[削除]ボタンをクリック
(3)削除の確認ダイアログが表示されるので[はい]をクリック
この段階でトランザクション管理を有効にするためBEGIN TRANSACTION命令を発行し、続けてDELETE命令で対象レコードを削除します。
(4)削除の再確認ダイアログが表示されるので[いいえ]をクリック
ここで[はい]をクリックするとCOMMIT TRANSACTION命令で処理が確定されてレコードは削除されます。[いいえ]をクリックすればROLLBACK
TRASACTION命令が発行され、先のDELETE命令による削除は取り消されます。
(5)削除が取り消された旨のメッセージが表示される
上記(4)の段階で[いいえ]をクリックすると、削除が取り消された旨のメッセージを表示します。Enterprise Managerでテーブル「商品_dmy」を開いて確認してください。
なお、操作の対象とするテーブルには、「商品_mr」と同じ内容を記録した「商品_dmy」を使っています。また、第14回の例では商品名と共に在庫数も表示するようにしていましたが、今回は「レコードの削除と取り消し処理」だけに絞って説明するため、在庫数の表示処理(テーブル「在庫_mr」との関連付け)は省略してあります。
画面1:テキストボックスに削除したい商品の商品IDを入力する
画面2:[検索]ボタンをクリックすると該当する商品名が表示される
画面3:削除の確認ダイアログが表示される
(ここでは[はい]をクリック)
画面4:SQL発行後に削除の再確認ダイアログが表示される
([いいえ]をクリック)
画面5:削除が取り消される
- Ifで確定/取消に分岐 -
上記処理の中心となる、削除と取り消し部分のソースを掲げておきます(アプリケーション全体については、サンプルのプロジェクトを開いてフォームのデザインとソースを確認してください)。
この処理は、[削除]ボタンをクリックしたときのイベントプロシージャ“btnDelete_Click”に割り当てています。
ソース中のアミ をかけた箇所(a)~(c)が、トランザクション管理でレコード削除の確定と取り消しを制御している部分です。BEGIN TRANSACTIONなどの命令も通常のSQL命令と同じくSqlCommandオブジェクトのCommandTextに文字列として設定し、ExecuteNonQueryメソッドでそれを実行します。
(a)BEGIN TRANSACTION命令を発行してトランザクションの管理を開始
その後、
objCommand.CommandText = strSql
If objCommand.ExecuteNonQuery >= 1 Then ' 削除実行
If MsgBox("本当に削除しますか?", _
MsgBoxStyle.Question.YesNo, "削除の再確認") _
= MsgBoxResult.Yes Then
として実際にDELETE命令を発行してレコードを削除します。続けてユーザーに削除の確認を求め、[はい]がクリックされたら(b)へ、[いいえ]がクリックされたら(c)へ制御を移行します。
(b)COMMIT TRANSACTION命令を発行して削除を確定します
(c)ROLLBACK TRANSACTION命令を発行して先のDELETE命令を取り消します
リスト1:レコードの削除と確定/取り消し処理のソース
' ------------------------------------------------
' 削除処理(対象レコードはグローバル変数から取得)
' ------------------------------------------------
Private Sub btnDelete_Click _
(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btnDelete.Click
Dim objConnect As New SqlConnection
Dim objCommand As New SqlCommand
Dim strMessage As String
Dim strSql As String
' 削除用の接続文字列を設定
strSql = _
"DELETE 商品_dmy WHERE 商品ID = " & strTargetId
' ユーザー宛の確認メッセージ
strMessage = "商品ID:" & strTargetId & vbCrLf & _
"品名:" & strTargetName & vbCrLf & _
"を削除します。よろしいですか?"
' 未検索時には処理を行わない
If (strTargetId = "") Or (strTargetName = "") Then
MsgBox("商品が特定されていません。", _
MsgBoxStyle.OKOnly, "商品エラー")
Exit Sub
End If
' ユーザーに削除の確認を求める
If MsgBox(strMessage, MsgBoxStyle.YesNo, "削除の確認") _
= MsgBoxResult.No Then
Exit Sub
End If
Try
' 接続文字列の設定
objConnect.ConnectionString = _
"Persist Security Info=False;Integrated Security=SSPI;" & _ "database=db1001ya;server=localhost"
' コネクションの設定
objCommand.Connection = objConnect
' 接続を開く
objConnect.Open()
' トランザクション開始 ------------------------------(a)
objCommand.CommandText = "BEGIN TRANSACTION"
objCommand.ExecuteNonQuery()
' SQLの設定
objCommand.CommandText = strSql
If objCommand.ExecuteNonQuery >= 1 Then ' 削除実行
If MsgBox("本当に削除しますか?", _
MsgBoxStyle.Question.YesNo, "削除の再確認") _
= MsgBoxResult.Yes Then
' コミット(削除を確定) ------------------------(b)
objCommand.CommandText = "COMMIT TRANSACTION"
objCommand.ExecuteNonQuery()
MsgBox("削除しました。", MsgBoxStyle.OKOnly, "削除完了")
Else ' ロールバック(削除を取消) --------------(c)
objCommand.CommandText = "ROLLBACK TRANSACTION"
objCommand.ExecuteNonQuery()
MsgBox("削除を取り消しました。", MsgBoxStyle.OKOnly, "削除取消")
End If
InitForm() ' 再実行に備えてテキストボックスとグローバル変数を初期化
Else ' 検索失敗
MsgBox("該当する商品が見つかりません。", _
MsgBoxStyle.OKOnly, "検索エラー")
Exit Sub
End If
Catch objExcept As Exception ' 例外処理
MsgBox(objExcept.ToString, MsgBoxStyle.OKOnly, "DBエラー")
Finally
' 接続を閉じる
If Not objConnect Is Nothing Then
objConnect.Close()
End If
End Try
End Sub
- 変数を使う方が合理的 -
サンプルではBEGIN、COMMIT、ROLLBACKの各命令の実行箇所を分かりやすくするため、実行の都度CommandTextに"BEGIN
TRANSACTION"などのSQL文字列を代入していますが、実際のプログラミングでは処理の冒頭でString型の変数を宣言し、以下のように各SQL文を予め代入しておく方が合理的です。
なお、この方法で記述した“btnDelete_Click”プロシージャのソースは、サンプルの“ex01source.txt”に記載してあります。
・SQLを保存するString型変数を宣言
Dim strBeginTran As String
Dim strCommit As String
Dim strRollBack As String
・各変数にSQL文字列を代入
strBeginTran = "BEGIN TRANSACTION"
strCommit = "COMMIT TRANSACTION"
strRollBack = "ROLLBACK TRANSACTION"
・CommandTextに変数を代入してSQLを発行
トランザクション管理の開始
objCommand.CommandText = strBeginTran
objCommand.ExecuteNonQuery()
トランザクションの確定
objCommand.CommandText = strCommit
objCommand.ExecuteNonQuery()
トランザクションの取消
objCommand.CommandText = strRollBack
objCommand.ExecuteNonQuery()
|
|
|