DataGridにレコードを更新する機能を追加したサンプル

図 DataGridにレコードを更新する機能を追加したサンプル
このサンプルは、親ウィンドウのDataGridからレコードを選択して子ウィンドウから編集することができます。子ウィンドウから編集したレコードは、親ウィンドウのDataGridに表示されます。
レコードを編集するには、親ウィンドウに表示されているDataGridからレコードを選択します。次に、親ウィンドウからレコードの更新ボタン
をクリックします。子ウィンドウのテキストボックスに選択したレコードが表示されたら、編集して子ウィンドウから[更新]ボタンをクリックします。子ウィンドウから更新ボタンをクリックしても、子ウィンドウは開いた状態になっていますので再更新することができます。[閉じる]のボタンをクリックすると、子ウィンドウを閉じます。
更新されたレコードは、親ウィンドウのDataGridに表示されます。DataGridには、得意先テーブルのレコードが得意先IDの降順に10件表示されます。
◆プログラムDataGridUpdate.aspx/PopupUpdate.aspxのポイント
¶ポイント1 DataGridに表示されていないカラムを編集するには
Web Matrixのテンプレートを使用すれば、DataGridにレコードを編集する機能を簡単に追加することができます。ところが、DataGridに編集機能を組み込んだ場合、編集できるレコードのフィールドがDataGridに表示されているカラムに限定されるため、あまり実用的ではありません。このサンプルでは、レコードの編集処理を、子ウィンドウに分離することによりこの問題を解決しています。子ウィンドウからは、DataGridに表示されていないカラムも編集することができます。また、子ウィンドウと親ウィンドウを連動させていますので、子ウィンドウで編集したレコードが親ウィンドウのDataGridに反映されます。
¶ポイント2 同時実行違反の対処
このサンプルでは、編集したレコードをデータベースに反映するのにDataAdapterのUpdate()メソッドを使用しています。Update()メソッドは、DataTableのレコードが変更されたときは、SQLのUPDATEステートメントを実行してデータベースに反映します。
Update()メソッドは、レコードが他のクライアントからすでに変更されているとき、「同時実行違反」のエラーとします。この場合、親ウィンドウのDataGridには最新のデータを再表示しますので、子ウィンドウに表示されている内容と比較することができます。子ウィンドウに表示されているデータで上書きしても問題なければ再度、更新ボタンをクリックします。2回目の更新ボタンをクリックしたときは、DataTableが最新のデータにリフレッシュされていますので正常に更新されます。
¶ポイント3 DataGridのOnItemCommandイベントで選択した行の主キーを取得するには
OnItemCommandイベントで選択した行の主キーを取得するには、DataGridのDataKeysコレクションを参照します。DataKeysコレクションの引数には、DataGridから選択したアイテムのインデックス番号を指定します。
mintCustomerID = dgrdCustomers.DataKeys(e.Item.ItemIndex)
なお、DataKeysコレクションは、DataGridのDataKeyFieldプロパティに主キーのカラム名を設定したとき有効です。
dgrdCustomers. DataKeyField = "CustomerID"
Page_Loadイベントから選択した行の主キーを取得するには、以下のように記述します。
mintCustomerID = dgrdCustomers.DataKeys(dgrdCustomers.SelectedIndex)
¶ポイント4 DataGridからアイテムを選択しているか調べるには
アイテムが選択されているか調べるには、DataGridのSelectedIndexプロパティを参照します。SelectedIndexに-1が格納されているときは、アイテムが選択されていません。
If dgrdCustomers.SelectedIndex = - 1 Then
・・・アイテムが選択されていないときの処理
End If
¶ポイント5 親ウィンドウから子ウィンドウに更新するレコードの得意先IDを渡すには
親ウィンドウから子ウィンドウに得意先IDを渡すには、QueryStringを使用します。
PopupUpdate.aspx?id=9999
子ウィンドウから得意先IDを取得するには、Request.QueryString、Request.Paramsプロパティを使用します。
Request.QueryString("id")
Request.Params("id")
¶ポイント6 レコードのカラム値がNullか調べるには
DataRowに格納されているレコードのカラム値がNullか調べるには、DataRowのIsNull()メソッドを参照します。
Dim dr As DataRow = dt.Ro
If dr.IsNull("Phone") Then
・・・電話番号がNullのときの処理
End If
◆メインプログラムDataGridUpdate.aspxの解説(HTML編)
親ウィンドウのWebフォームには、ImageButtonとDataGridを作成しています。ImageButtonでは、レコードの更新ボタンを表示します。このボタンをクリックすると、子ウィンドウが開きます。DataGridには、得意先テーブルのレコードを得意先IDの降順に10件表示します。
行151-157では、ImageButtonを定義しています。行153では、OnCommandイベントを登録しています。このイベントでは、子ウィンドウを開きます。
151: <asp:ImageButton
id="ibtnUpdate" runat="server"
152:
CommandName="update"
153:
OnCommand="ibtnUpdate_Command"
154:
ImageUrl="../img/update.gif"
157: />
行158-164では、LabelとTextBoxを定義してDataGridの件数を表示しています。TextBoxのReadOnlyプロパティには、Trueを設定して読み込み専用にしています。TextBoxには、ランタイム時にレコード件数を設定します。
158: <asp:Label id="lblRo
159: Text="件数"
160: />
161: <asp:TextBox id="txtRo
163: Columns="3"
164:
ReadOnly="True" />
行177-229では、DataGridを定義しています。このDataGridでは、AutoGenerateColumnsプロパティにFalseを設定してカラムの自動生成機能を抑止しています。行191-228の<Columns>…</Columns>では、TemplateColumnとBoundColumnを定義しています。TemplateColumnのItemTemplateでは、LinkButtonを定義しています。LinkButtonは、レコードセレクターとして使用します。BoundColumnでは、得意先テーブルの得意先ID、得意先名、担当者名、役職、電話番号、都道府県をバインドしています。
191: <Columns>
192: <asp:TemplateColumn
193:
HeaderText="<div
class='dgrdHeaderBox'>1</div>">
194:
<ItemTemplate>
195:
<asp:LinkButton id="lbtnSelect" runat="server"
196:
CommandName="Select"
197:
Text="<div class='dgrdItemArrow'>4</div>"
198:
Visible="True" />
199:
</ItemTemplate>
202:
</asp:TemplateColumn>
203: <asp:BoundColumn ItemStyle-Width="20"
204:
DataField="CustomerID"
205:
HeaderText="<div class='dgrdHeader'>ID</div>">
207:
</asp:BoundColumn>
・・・
228: </Columns>
行238-243では、TextBoxを定義しています。このTextBoxは、メッセージを表示するのと、Webページをポストバックさせる役割をします。
238: <asp:TextBox id="txtMessage"
runat="server"
241: Columns="107"
242: Visible="True"
243: ReadOnly="True" />
行248-251では、Buttonを定義しています。このButtonもWebページをポストバックさせる役割をします。
248: <asp:Button id="btnRefresh"
runat="server"
249: Text="Hidden"
250: Visible="False"
251:
OnClick="btnRefresh_Click" />
リスト DataGridUpdate.aspxのソースコード(HTML編)
|
132:
<html> 191: <Columns> 199:
</ItemTemplate> 228: </Columns> |
◆メインプログラムDataGridUpdate.aspxの解説(コード編)
DataGridUpdate.aspxは、DataGrid上に得意先テーブルを表示します。DataGridからレコードを選択して、更新ボタンをクリックすると、子ウィンドウを開きます。また、子ウィンドウと連携して、子ウィンドウから編集したレコードをDataGridに表示する処理も行っています。
Sub Page_Load()イベントの処理
このイベントは、DataGridUpdate.aspxがロードされたときに実行されます。このイベントでは、クライアント側で動作するイベントの登録と、DataGridに得意先テーブルをバインドします。
行11では、メッセージを表示するTextBoxにクライアント側で動作する、onPropertyChangeイベントを登録しています。onProperyChangeイベントでは、Webページをポストバックします。GetPostBackEventReference()メソッドは、WebページをポストバックするJavaScriptを生成します。Webページがポストバックされると、btnRefreshイベントが実行されます。
行12-21のIf…Else…End Ifでは、ページが最初にロードされたか調べています。ページが最初にロードされたときは、Vie
|
10: Sub Page_Load() |
Sub dgrdCustomers_ItemDataBound()イベントの処理
このイベントは、DataGridのDataBind()メソッドが実行されたときに発生します。このイベントでは、DataGridのアイテム(DataGridItem)にクライアント側で動作するonClickイベントを登録しています。これにより、DataGridの任意のセルをクリックして行を選択できるようになります。
|
38: Sub
dgrdCustomers_ItemDataBound(s As Object, e As DataGridItemEventArgs) |
Sub dgrdCustomers_ItemCommand()イベントの処理
このイベントは、DataGridから行をクリックしたときに発生します。このイベントでは、DataGridから選択した行の情報をVie
行52では、DataGridのDataKeysコレクションから選択された行の主キー(得意先ID)を取得しています。Item.ItemIndexには、選択されたアイテムのインデックス番号が格納されています。行53では、得意先IDをVie
|
50: Sub
dgrdCustomers_ItemCommand(s As Object, e As DataGridCommandEventArgs) |
Sub ibtnUpdate_Command()イベントの処理
このイベントは、Webページからレコードの更新ボタンをクリックしたときに発生します。このイベントでは、レコード更新用の新規ウィンドウを表示します。
行59-61のIf…End Ifでは、DataGridから更新するレコードを選択しているか調べています。レコードが選択されているときは、InsertScriptBlock()関数を呼び出して新規ウィンドウを開きます。この関数の引数には、更新するレコードの得意先IDを指定します。
|
58: Sub
ibtnUpdate_Command(s As Object, e As CommandEventArgs) |
Sub btnRefresh_Click()イベントの処理
このイベントは、クライアント側からメッセージを表示するTextBoxを書き換えたときに発生します。このサンプルでは、子ウィンドウから親ウィンドウのTextBoxにメッセージを設定して書き換えます。つまり、子ウィンドウから親ウィンドウをポストバックさせています。btnRefresh_Clickイベントでは、DataGridに得意先テーブルをバインドしてリフレッシュします。
|
24: Sub
btnRefresh_Click(s As Object, e As EventArgs) |
Sub BindDataGrid()の処理
このサブプロシージャでは、DataGridに得意先テーブルをバインドして表示します。BindDataGridは、Page_Loadイベントから呼ばれます。
行65では、得意先テーブルからレコードを抽出するSQLを生成しています。このSQLでは、Order By句で「CustomerID Desc」を指定していますので、得意先IDの降順にレコードが並べ替えられます。また、Top 10のオプションを指定していますので、上位10件のレコードが抽出されます。
行66では、CreateDataSet()関数を呼び出して得意先テーブルのDataSetを作成しています。行67では、DataSetのTablesコレクションからDataTableを作成しています。行68では、DataTableのPrimaryKeyプロパティに得意先IDのDataColumnを設定しています。PrimaryKeyに主キーを設定することにより、DataTableのRo
行69-76のWith…End Withでは、DataGridにDataTableをバインドしています。行73では、DataGridのSelectedIndexプロパティに0を設定して、DataGridの先頭行を選択した状態にしています。行74-75では、先頭行の得意先IDを取得してVie
行77では、件数のTextBoxにレコード件数を設定しています。行78では、Session変数にDataTableを保存しています。ここで保存したSession変数は、ポストバックされたときと、サブプログラムから参照します。
|
64: Sub BindDataGrid() |
Sub InsertScriptBlock()の処理
このサブプロシージャでは、新規ウィンドウを開くJavaScriptを生成して登録します。InsertScriptBlockは、レコードの更新ボタンをクリックしたときに、更新ボタンのOnCommandイベントから呼ばれます。
行82-84では、JavaScriptのwindow.open()メソッドの引数に指定するオプションを生成しています。行86-90のWith…End Withでは、StringBuilderのAppend()メソッドで以下のJavaScriptを生成しています。
<script
language='javascript'>
window.open('PopupUpdate.aspx?id=9999','_blank','features');
</script>
JavaScriptのwindow.open()メソッドは、新規ウィンドウを開きます。Open()メソッドの引数には、url、target、featuresを指定します。urlには、新規ウィンドウに表示するファイルPopupUpdate.aspxを指定します。?id=9999は、QueryStringと呼ばれるパラメータです。このサンプルでは、親ウィンドウから子ウィンドウにデータを渡すのにQueryStringを使用します。Id=には、更新するレコードの得意先IDを指定します。
行91では、Page.RegisterClientScriptBlock()メソッドでJavaScriptを登録します。ここで登録したJavaScriptは、Webページがロードされたときにクライアント側のブラウザから実行されます。
|
81: Sub
InsertScriptBlock(intCustomerID As Integer)
|
Sub InsertAlertScript()の処理
このサブプロシージャでは、エラーメッセージをポップアップウィンドウに表示するJavaScriptを生成して登録します。InsertAlertScriptは、CreateDataSet()関数からエラーが発生したときに呼ばれます。ここで登録したJavaScriptは、Webページがロードされたときにクライアント側のブラウザから実行されます。
|
94: Sub
InsertAlertScript(strMessage As String) |
Function CreateDataSet()関数の処理
この関数は、DataSetを作成して返します。CreateDataSetは、BindDataGrid()から呼ばれます。
行117-118では、Connectionのインスタンスを生成しています。Connectionの引数には、Web.Configに登録されているデータベース接続文字列を指定しています。Web.Configに登録されている内容を取得するには、ConfigurationSettingsのAppSettings()メソッドを使用します。AppSettings()メソッドの引数には、<add>タグのkeyを指定します。
117: Dim con As New OleDbConnection( _
118:
ConfigurationSettings.AppSettings("conStringAccNw"))
<appSettings>
<add key="conStringAccNw"
value="PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA Source=C:\WebMatrix\webdb\Nwind.mdb" />
</appSettings>
行119では、DataAdapterのインスタンスを生成しています。DataAdapterの引数には、SQLとConnectionオブジェクトを指定しています。
行121-126のTry…Catch…End Tryブロックでは、DataAdapterのFill()メソッドでSQLを実行して得意先テーブルをDataSetに取り込んでいます。行121-122のTryブロックでエラーが発生したときは、行123-125のCatchブロックが実行されます。Catchブロックでは、InsertAlertScript()を呼び出してポップアップウィンドウにエラーメッセージを表示します。
121: Try
122: da.Fill(ds)
123: Catch e As Exception
124:
InsertAlertScript(e.Message)
125: Return Nothing
126: End Try
行127では、関数の戻り値としてDataSetを返します。
|
115:
Function CreateDataSet(strSQL As String, _ |
リスト DataGridUpdate.aspxのソースコード(コード編)
|
1: <%@ Page
language="vb" SmartNavigation="false" %> |
◆サブプログラムPopupUpdate.aspxの解説(HTML編)
子ウィンドウのWebフォームには、TextBoxとButtonを作成しています。TextBoxには、得意先レコードが表示されますので編集することができます。
行105-182の<fieldset>…</fieldset>では、角の丸みがかったボックスを表示しています。行106-110の<legend>…</legend>では、ボックスの凡例を表示しています。
行112-124の<tr>…</tr>では、得意先IDのLabelとTextBoxを定義しています。TextBoxには、得意先レコードの得意先IDが表示されます。得意先IDは変更することができませんので、TextBoxのReadOnlyプロパティにTrueを設定して読み込み専用にしています。
行126-140の<tr>…</tr>では、得意先名のLabelとTextBoxを定義しています。行136-138では、RequiredFieldValidatorで得意先名が入力されているかチェックしています。得意先名を入力しないで更新ボタンをクリックすると、TextBoxの右側に「*」が表示されます。
後続する<tr>…</tr>では、担当者名、部署役職、電話番号のLabelとTextBoxを定義しています。
行185-225の<table>…</table>には、ImageButton、Label、DropDownList、Buttonを定義しています。ImageButtonとDropDownListのEnabledプロパティには、Falseを設定して使用不可にしています。このサンプルでは、これらの機能はサポートしていません。行215-222では、「更新」と「閉じる」のボタンを定義しています。「閉じる」のボタンには、CausesValidationプロパティにFalseを設定してRequiredFieldValidatorを適用させないようにしています。
リスト PopupUpdate.aspxのソースコード(HTML編)
|
97: <html> |
◆ サブプログラムPopupUpdate.aspxの解説(コード編)
PopupUpdate.aspxは、Webフォームから編集したレコードを2段階でデータベースに反映します。Webフォームから編集したレコードは、一旦DataTable上で更新されます。さらに、DataTableの変更されたレコードをデータベースに反映します。編集したレコードをデータベースに反映したら、親ウィンドウをポストバックさせてDataGrid上に表示します。
Sub Page_Load()イベントの処理
このイベントは、ページがロードされたときに発生します。Page_Loadでは、ページの初期化処理を行います。
行9では、Session変数に保存されている得意先テーブルのDataTableを取得して変数に退避します。
行10-14のIf…EndIfでは、ページが最初にロードされたか調べています。最初にロードされたときは、「閉じる」ボタンにクライアント側で動作するonClickイベントを登録しています。onClickイベントでは、JavaScriptのwindow.close()メソッドを実行して子ウィンドウを閉じます。次に、AddCursor()を呼び出してアプリケーション独自のカーソルを表示しています。最後に、DisplayRecord()を呼び出してTextBoxに得意先レコードを表示します。
|
8: Sub Page_Load() |
Sub btnUpdate_Click()イベントの処理
このイベントは、更新ボタンをクリックしたときに発生します。このイベントでは、得意先テーブルのレコードを更新します。また、ここで更新したレコードを親ウィンドウのDataGridに反映させます。
行18では、UpdateRecord()関数を呼び出して得意先テーブルのレコードを更新します。UpdateRecordからは、処理の結果がメッセージで返されます。行20-28のWith…End Withでは、StringBuilderのAppend()メソッドで以下のJavaScriptを生成しています。
<script
language='javascript'>
window.opener.frmMain.txtMessage.value =
'XXX';
alert('同時実行違反発生!');
</script>
JavaScriptのwindow.opener.frmMain.txtMessage.value=は、親ウィンドウのtxtMessage.valueにメッセージを設定します。txtMessageには、クライアント側で動作するonProperyChangeイベントが登録されていますので、このイベントが実行されます。onPropertyChangeイベントには、WebページをポストバックさせるJavaScriptが記述されていますので、WebページがポストバックされてDataGridがリフレッシュされます。これで親ウィンドウのDataGridには、子ウィンドウから更新したレコードが表示されます。
JavaScriptのalert()関数は、「同時実行違反」のエラーが発生したときに生成されます。alert()関数は、ポップアップウィンドウにエラーメッセージを表示します。
行29では、Page.RegisterClientScriptBlock()メソッドでJavaScriptを登録しています。ここで登録した、JavaScriptは、Webページがロードされたときクライアント側のブラウザから実行されます。
|
17: Sub btnUpdate_Click(s
As Object, e As EventArgs) |
Sub AddCursor()の処理
このサブプロシージャでは、アプリケーション独自のカーソルを追加します。AddCursorは、Page_Loadイベントからページが最初にロードされたときに呼ばれます。
カーソルを追加するには、TextBoxにクライアント側で動作するonFocusとonBlurイベントを登録します。onFocusイベントは、TextBoxがフォーカスを取得したときに発生します。onBlurは、フォーカスを喪失したときに発生します。これらのイベントで、TextBoxの背景色を書き換えることによりアプリケーション独自のカーソルを表示することができます。
TextBoxにクライアント側で動作するイベントを登録するには、AttributesコレクションのAdd()メソッドを使用します。Add()メソッドの引数には、イベント名とイベント処理を記述します。
onFocusイベントでは、TextBoxの背景色をLightGreenに書き換えます。onBlueイベントでは、TextBoxの背景色をAliceBlueに戻します。
|
44: Sub AddCursor() |
Sub DisplayRecord()の処理
このサブプロシージャでは、TextBoxに得意先テーブルのレコードを表示します。DisplayRecordは、Page_Loadイベントからページが最初にロードされたときに呼ばれます。
行33では、RequestのParamsコレクションからQueryStingに指定しているパラメータを取得しています。QueryStringには、親ウィンドウのDataGridから選択したレコードの得意先IDが指定されています。Request.Params()の代わりにRequest.QueryString()を使用することもできます。
PupupUpdate.aspx?id=9999
Request.Params("id") è 9999
Request.QueryString("id") è 9999
行34では、DataTableのRo
行35-41のIf…End Ifでは、レコードが見つかったか調べています。レコードが見つかったときは、DataRowから得意先ID、得意先名、担当者名、部署役職、電話番号を取得してTextBoxに表示します。担当者名、役職部署、電話番号は、Nullの可能性があるためDataRowのIsNull()メソッドで調べています。Nullのときは、空白を表示します。
|
32: Sub DisplayRecord() |
Function UpdateRecord()関数の処理
この関数では、DataTableのレコードを更新します。UpdateRecord()は、更新ボタンのOnClickイベントから呼ばれます。
行60-64では、TextBoxから得意先ID、得意先名、担当者名、部署役職、電話番号を取得しています。行67では、DataTableのRo
行75では、UpdateDataTable()関数を呼び出して、DataTableの変更されたレコードをデータベースに反映しています。
ここでは、DataRowのカラムを更新するときBeginEdit/EndEidtを使用していますが直接カラムを更新することもできます。BeginEditは、途中で更新をキャンセルするときに使用します。BeginEditを使用しないでカラムを更新したときは、途中でキャンセルすることはできません。
dr.BeginEdit
dr("CompanyName") =
strCompanyName
dr("ContactName") =
strContactName
dr("ContactTitle") =
strContactTitle
dr("Phone") = strPhone
dr.EndEdit
or dr.CancelEdit è 更新を確定、またはキャンセルする
|
58: Function
UpdateRecord() As String
|
Function UpdateDataTable()関数の処理
この関数では、DataTableの変更されたレコードをデータベースに反映します。この関数は、UpdateRecord()から呼ばれます。UpdateDataTable()の引数には、strSQLとstrConnectionStringを指定します。strSQLには、得意先テーブルからレコードを抽出するSQLを指定します。strConnectionStringには、データベースの接続文字列を指定します。DataTableをデータベースに反映するには、DataAdapterのUpdate()メソッドを使用します。Update()メソッドで使用するINSERT、UPDATE、DELETEのSQLは、CommandBuilderで自動生成します。
行80-81では、Connectionのインスタンスを生成しています。Connectionの引数には、データベースの接続文字列を指定します。行82では、DataAdapterのインスタンスを生成しています。DataAdapterの引数には、SQLとConnectionのオブジェクトを指定します。引数のSQLには、SELECTステートメントを指定します。行83では、CommandBuilderでDataTableをデータベースに反映するためのSQLを自動生成します。CommandBuilderは、SELECTステートメントを元にINSERT、UPDATE、DELETEのSQLを生成します。
行86-91のTry…Catch…End Tryブロックでは、DataAdapterのUpdate()メソッドでDataTableの変更されたレコードをデータベースに反映します。DataTableに新規レコードが追加されたときは、SQLのINSERTステートメントを実行してDataTableのレコードをデータベースに追加します。DataTableのレコードが更新されたときは、UPDATEステートメントで、データベースのレコードを更新します。DataTableのレコードが削除されたときは、DELETEステートメントで、データベースからレコードを削除します。データベースのレコードを更新、削除するときは、他のユーザから変更されていないことを確認してから実行します。他のユーザから変更されているときは、同時実行違反のエラーになります。
Update()メソッドでエラーが発生したときは、行89-90のCatchブロックが実行されます。行92では、戻り値として処理の結果を示すメッセージを返します。
同時実行違反のエラーが発生したときは、ポップアップウィンドウに「同時実行違反発生!」のエラーメッセージが表示されます。このとき、親ウィンドウのDataGridには最新のデータが表示されますので、子ウィンドウのデータと比較することができます。子ウィンドウから再度、更新ボタンをクリックしたときは、親ウィンドウにてDataTableをリフレッシュしていますので正常に更新されます。
|
78: Function
UpdateDataTable(strSQL As String, _ |
リスト PopupUpdate.aspxのソースコード(コード編)
|
1: <%@ Page
language="vb" SmartNavigation="False" %> |
Note
|
DataAdapterのUpdate()メソッドで使用するUPDATEステートメントを手動にて作成して改善するには DataAdapterのSelectCommandに、以下のようなSELECTステートメントを設定して、CommandBuilderを実行すると、得意先レコードの得意先ID、得意先名、担当者名、部署役職、電話番号が他のクライアントから変更されていないことを確認してからレコードを更新します。 Dim strSQL As String = "Select CustomerID, CompanyName, ContactName,
Dim con As New OleDbConnection( _ ConfigurationSettings.AppSettings(strConnectionString)) Dim da As New OleDbDataAdapter(strSQL, con) Dim cb As New OleDbCommandBuilder(da) CommandBuilderが生成したUPDATEステートメント: UPDATE Customers SET CompanyName = ? , ContactName = ? , ContactTitle = ? , Phone = ? WHERE ( (CustomerID = ?) AND ((? IS NULL AND CompanyName IS NULL) OR (CompanyName = ?)) AND ((? IS NULL AND ContactName IS NULL) OR (ContactName = ?)) AND ((? IS NULL AND ContactTitle IS NULL) OR (ContactTitle = ?)) AND ((? IS NULL AND Phone IS NULL) OR (Phone = ?)) ) DataAdapterのSelectCommandに、Select * From CustomersのようなSELECTステートメントを設定してCommandBuilderを実行すると、得意先レコードのすべてのフィールドが変更されていないことを確認してからレコードを更新します。このように、レコードのフィールド数が多いときは、CommandBuilderが生成したUPDATEステートメントはあまり効率よくありません。 UPDATEステートメントで、すべてのフィールドをチェックする代わりにConcurrencyID、タイムスタンプなどを利用すると性能を改善することができます。この場合、CommandBuilderを使用しないで手動にてUPDATEステートメントを作成します。ConcurrencyIDには、レコードの更新回数を格納します。 da.UpdateCommand = CreateUpdateCommand() Function CreateUpdateCommand() As OleDbCommand Dim sbSQL As New StringBuilder() With sbSQL .Append("Update Customers " & vbCrLf) .Append(" Set CompanyName = ?, " & vbCrLf) .Append(" ContactName = ?, " & vbCrLf) .Append(" ContactTitle = ?, " & vbCrLf) .Append(" Phone = ?, " & vbCrLf) .Append(" ConcurrencyID = ConcurrencyID + 1 " & vbCrLf) .Append(" Where CustomerID = ? And " & vbCrLf) .Append(" ConcurrencyID = ? ") End With Dim cmd As New OleDbCommand(sbSQL.ToString, mcon) Dim pc As OleDbParameterCollection = cmd.Parameters Dim param As OleDbParameter With pc .Add("@NewCompanyName", OleDbType.VarWChar, 40, "CompanyName") .Add("@NewContactName", OleDbType.VarWChar, 30, "ContactName") .Add("@NewContactTitle", OleDbType.VarWChar, 30, "ContactTitle") .Add("@NewPhone", OleDbType.VarWChar, 24, "Phone")
param = .Add("@OrgCustomerID", OleDbType.Integer, 0, "CustomerID") param.SourceVersion = DataRowVersion.Original param = .Add("@OrgConcurrencyID", OleDbType.Integer, 0, "ConcurrencyID") param.SourceVersion = DataRowVersion.Original End With Return cmd End Function 手動にて作成したUPDATEステートメントのWHERE句では、CustomerIDとConcurrencyIDをチェックするだけで、レコードが変更されていないことを確認することができますので性能が改善されます。 Update Customers Set CompanyName = ?, ContactName = ?, ContactTitle = ?, Phone = ?, ConcurrencyID = ConcurrencyID + 1 Where CustomerID = ? And ConcurrencyID = ? DataRowVersion.Originalは、WHERE句のパラメータ@OrgCustomerIDと@OrgConcurrencyIDに変更前の値を代入することを意味します。 param = .Add("@OrgCustomerID", OleDbType.Integer, 0, "CustomerID") param.SourceVersion = DataRowVersion.Original param = .Add("@OrgConcurrencyID", OleDbType.Integer, 0, "ConcurrencyID") param.SourceVersion = DataRowVersion.Original |
Tip
|
Vie Vie Vie Vie Vie |
Tip
|
更新ボタンをクリックしたときに確認の問い合わせをするには(Validatorコントロールも使用可) 更新ボタンに確認の問い合わせを追加するには、Page_Loadイベントに以下のコードを追加します。 btnUpdate.Attributes.Add("onclick", "return confirm(更新してよろしいですか?);") ところが、RequiredFieldValidatorなどのValidatorコントロールを使用しているときは、更新ボタンのonClickイベントが競合するために正常に動作しません。この不都合を回避するには、更新ボタンを<span>…</span>タグで囲って、onClickイベントを追加します。 <span onClick="return confirm('更新してよろしいですか?');"> <asp:Button id="btnUpdate" runat="server" Text="更新" Style="vertical-align:middle" OnClick="btnUpdate_Click" /> </span> これで、更新ボタンをクリックすると確認のメッセージが表示されます。ところが、Validatorコントロールでエラーを検出したときは、エラーメッセージが表示される前に確認のメッセージが表示されます。Webフォームにエラーが無いときのみ確認のメッセージを表示するには、confirm()メソッドの代わりにconfirmUpdate()関数を呼びます。これで、エラーが無いときのみ問い合わせのメッセージが表示されます。confirmUpdate()関数は、<head>…</head>タグに挿入するか、Page.RegisterClientScriptBlock()メソッドでランタイム時に登録します。 function confirmUpdate() { if (typeof(Page_ClientValidate) != 'function' || Page_ClientValidate()) { return confirm('更新してよろしいですか?'); } else { return false; } } </script> <span onClick="return confirmUpdate();"> <asp:Button id="btnUpdate" runat="server" Text="更新" Style="vertical-align:middle" OnClick="btnUpdate_Click" /> </span> |