SqlDataSource でデータを挿入、更新、削除する (VB)
前のチュートリアルでは、ObjectDataSource コントロールによって行えるデータの挿入、更新、削除の方法について学習しました。 SqlDataSource コントロールでも同じ操作がサポートされていますが、そのアプローチは異なります。このチュートリアルでは SqlDataSource を構成して、データを挿入、更新、削除する方法について説明します。
はじめに
「挿入、更新、削除の概要」で説明したように、GridView コントロールには組み込みの更新機能と削除機能が用意されているのに対し、DetailsView コントロールと FormView コントロールには、編集および削除機能と共に挿入サポートが含まれています。 これらのデータ変更機能は直接、データ ソース コントロールに接続できます (コード行の記述は不要)。 「挿入、更新、削除の概要」では、GridView、DetailsView、FormView の各コントロールによる挿入、更新、削除を容易にする ObjectDataSource の使用について詳しく取り上げました。 別の方法として、ObjectDataSource の代わりに SqlDataSource を使用することもできます。
挿入、更新、削除をサポートするには、ObjectDataSource ではオブジェクト レイヤー メソッドを指定して、挿入、更新、削除のアクションの実行を呼び出す必要があったことを思い出してください。 SqlDataSource では、実行する INSERT
、UPDATE
、DELETE
の各 SQL ステートメント (またはストアド プロシージャ) を指定する必要があります。 このチュートリアルで説明していきますが、これらのステートメントは手動で作成することも、SqlDataSource のデータ ソースの構成ウィザードで自動的に生成することもできます。
Note
GridView、DetailsView、FormView の各コントロールの挿入機能、編集機能、削除機能については既に説明したので、このチュートリアルでは、これらの操作をサポートするよう SqlDataSource コントロールを構成することに重点を置きます。 GridView、DetailsView、FormView 内でのこれらの機能の実装を復習したい場合は、「挿入、更新、削除の概要」から始まる、データの編集、挿入、削除に関するチュートリアルを見直してください。
ステップ 1: INSERT、UPDATE、DELETE の各ステートメントを指定する
前の 2 つのチュートリアルで説明したように、SqlDataSource コントロールからデータを取得するには、次の 2 つのプロパティを設定する必要があります。
ConnectionString
: クエリを送信するデータベースを指定します。SelectCommand
: 実行して結果を返すアドホック SQL ステートメントまたはストアド プロシージャ名を指定します。
パラメーターを持つ SelectCommand
値の場合、パラメーター値は SqlDataSource の SelectParameters
コレクションを用いて指定され、ハードコーディングされた値、共通のパラメーター ソース値 (querystring フィールド、セッション変数、Web コントロール値など) を含めたり、プログラムで割り当てたりすることができます。 SqlDataSource コントロールの Select()
メソッドがプログラムによって、またはデータ Web コントロールから自動的に呼び出されると、データベースへの接続が確立されて、パラメーター値がクエリに割り当てられ、コマンドがデータベースに送り出されます。 結果は、コントロールの DataSourceMode
プロパティの値に応じて、DataSet または DataReader として返されます。
データの選択と併せて、ほぼ同様の方法で INSERT
、UPDATE
、DELETE
の各 SQL ステートメントを指定することで、SqlDataSource コントロールを使用して、データの挿入、更新、削除を行うことができます。 単純に InsertCommand
、UpdateCommand
、DeleteCommand
のプロパティに INSERT
、UPDATE
、DELETE
の各 SQL ステートメントを割り当てて実行します。 ステートメントにパラメーターがある場合 (ほとんどの場合と同様)、パラメーターを InsertParameters
、UpdateParameters
、DeleteParameters
のコレクションに含めます。
InsertCommand
、UpdateCommand
、DeleteCommand
の値を指定すると、対応するデータ Web コントロールのスマート タグの [挿入を有効にする]、[編集を有効にする]、[削除を有効にする] の各オプションを利用できるようになります。 これを説明するために、「SqlDataSource コントロールを使用したデータのクエリ」チュートリアルで作成した Querying.aspx
ページの例を取り上げ、これを拡張して削除機能を含むようにします。
まず、SqlDataSource
フォルダーから InsertUpdateDelete.aspx
と Querying.aspx
のページを 開きます。 Querying.aspx
ページのデザイナーから、最初の例の SqlDataSource と GridView (ProductsDataSource
コントロールと GridView1
コントロール) を選択します。 2 つのコントロールの選択後、[編集] メニューに移動し、[コピー] を選択します (または Ctrl キーを押しながら C キーを押します)。 次に、InsertUpdateDelete.aspx
のデザイナーに移動し、そのコントロールに貼り付けます。 2 つのコントロールを InsertUpdateDelete.aspx
に移動した後、ブラウザーでページをテストします。 Products
データベース テーブル内のすべてのレコードの ProductID
、ProductName
、UnitPrice
の各列の値が表示されます。
図 1: すべての製品が ProductID
順に一覧表示されています (クリックするとフルサイズの画像が表示されます)
SqlDataSource の DeleteCommand プロパティと DeleteParameters プロパティの追加
この時点で、単純に Products
テーブルのすべてのレコードを返す SqlDataSource と、このデータをレンダリングする GridView があります。 この例を広げて、ユーザーが GridView を介して製品を削除できるようにすることが目標です。 これを実現するには、SqlDataSource コントロールの DeleteCommand
プロパティと DeleteParameters
プロパティの値を指定し、削除をサポートするように GridView を構成する必要があります。
DeleteCommand
プロパティと DeleteParameters
プロパティは、次のような、さまざまな方法で指定できます。
- 宣言構文を使用して
- デザイナーのプロパティ ウィンドウから
- データ ソースの構成ウィザードの [カスタム SQL ステートメントまたはストアド プロシージャを指定する] 画面から
- データ ソースの構成ウィザードのビューのテーブルから列を指定する画面の [詳細] ボタンを使用して (これにより、
DeleteCommand
プロパティとDeleteParameters
プロパティで使用されるDELETE
SQL ステートメントとパラメーター コレクションが事実上、自動的に生成されます)
ステップ 2 で DELETE
ステートメントを自動的に作成する方法について説明します。 ここでは、デザイナーのプロパティ ウィンドウを使用しますが、データ ソースの構成ウィザードや宣言構文のオプションも同様に、適切に機能します。
InsertUpdateDelete.aspx
のデザイナーで ProductsDataSource
SqlDataSource をクリックし、プロパティ ウィンドウを表示します ([表示] メニューから [プロパティ ウィンドウ] を選択するか、F4 キーを押します)。 DeleteQuery プロパティを選択すると、省略記号のセットが表示されます。
図 2: [プロパティ] ウィンドウで DeleteQuery プロパティを選択する
Note
SqlDataSource には DeleteQuery プロパティがありません。 もっと正確に言えば、DeleteQuery は DeleteCommand
プロパティと DeleteParameters
プロパティの組み合わせであり、デザイナーでウィンドウを表示する場合にのみプロパティ ウィンドウに表示されます。 ソース ビューのプロパティ ウィンドウで表示する場合は、代わりに DeleteCommand
プロパティが表示されます。
DeleteQuery プロパティの省略記号をクリックして、[コマンドおよびパラメーターのエディター] ダイアログ ボックスを表示します (図 3 を参照)。 このダイアログ ボックスで、DELETE
SQL ステートメントとパラメーターを指定できます。 [DELETE
コマンド] テキストボックスに次のクエリを 入力します (手動でも、クエリ ビルダーを使用してでもかまいません)。
DELETE FROM Products
WHERE ProductID = @ProductID
次に、[パラメーターの更新] ボタンをクリックして、下のパラメーターの一覧に @ProductID
パラメーターを追加します。
@ProductID パラメーターが DELETE コマンド パラメーターの一覧に追加されました。 />
図 3: プロパティ ウィンドウで DeleteQuery プロパティを選択する (クリックするとフルサイズの画像が表示されます)
このパラメーターには値を指定しないでください (パラメーター ソースは None のままにします)。 GridView に削除のサポートを追加すると、GridView は、[削除] ボタンがクリックされた行の DataKeys
コレクションの値を使用して、このパラメーター値を自動的に指定します。
Note
DELETE
クエリで使用されるパラメーター名は、GridView、DetailsView、FormView の DataKeyNames
値の名前と同じである必要があります。 つまり、DELETE
ステートメントのパラメーター名は意図的に @ProductID
(たとえば @ID
ではなく) にしています。Products テーブルの主キー列名 (つまり、GridView の DataKeyNames 値) が ProductID
だからです。
パラメーター名と DataKeyNames
値が一致しない場合、GridView はパラメーターに DataKeys
コレクションの値を自動的に割り当てることができません。
[コマンドおよびパラメーターのエディター] ダイアログ ボックスに削除関連の情報を入力した後、[OK] をクリックし、ソース ビューに移動して、結果の宣言型マークアップを確認します。
<asp:SqlDataSource ID="ProductsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand=
"SELECT [ProductID], [ProductName], [UnitPrice] FROM [Products]"
DeleteCommand="DELETE FROM Products WHERE ProductID = @ProductID">
<DeleteParameters>
<asp:Parameter Name="ProductID" />
</DeleteParameters>
</asp:SqlDataSource>
DeleteCommand
プロパティと <DeleteParameters>
セクション、および productID
という名前のパラメーター オブジェクトが追加されていることに注意してください。
削除用の GridView の構成
DeleteCommand
プロパティを 追加したことで、GridView のスマート タグに [削除を有効にする] オプションが含まれるようになりました。 このチェックボックスをオンにしてください。 「挿入、更新、削除の概要」で説明したように、これにより、GridView にはその ShowDeleteButton
プロパティが True
に設定された CommandField が追加されます。 図 4 に示すように、ブラウザーからページにアクセスすると、[削除] ボタンが表示されています。 いくつかの製品を削除して、このページをテストしてみましょう。
図 4: 各 GridView 行に削除ボタンが追加されました (クリックするとフルサイズの画像が表示されます)
[削除] ボタンをクリックするとポストバックが発生し、GridView によって ProductID
パラメーターに、Delete ボタンがクリックされた行の DataKeys
コレクション値の値が割り当てられ、SqlDataSource の Delete()
メソッドが呼び出されます。 次に、SqlDataSource コントロールをデータベースに接続し、DELETE
ステートメントを実行します。 その後、GridView は SqlDataSource に再バインドし、現在の製品セットを取得して表示します (ここではもう削除されたレコードは含まれていません)。
Note
GridView は DataKeys
コレクションを使用して SqlDataSource パラメーターを設定するため、GridView の DataKeyNames
プロパティを主キーを構成する列に設定し、SqlDataSource の SelectCommand
がこれらの列を返す必要があります。 さらに、SqlDataSource の DeleteCommand
のパラメーター名が @ProductID
に設定されていることが重要です。 DataKeyNames
プロパティが設定されていない場合、またはパラメーター名が @ProductsID
ではない場合、[削除] ボタンをクリックするとポストバックは発生しますが、実際にはどのレコードも削除されません。
図 5 は、この相互作用を図示しています。 データ Web コントロールの挿入、更新、削除に関連するイベントのチェーンの詳細については、「挿入、更新、削除に関連するイベントについての解説」チュートリアルを参照してください。
図 5: GridView の [削除] ボタンをクリックすると、SqlDataSource の Delete()
メソッドが呼び出される
ステップ 2: INSERT
、UPDATE
、DELETE
の各ステートメントを自動的に生成する
ステップ 1 で述べたとおり、INSERT
、UPDATE
、DELETE
の各 SQL ステートメントはプロパティ ウィンドウまたはコントロールの宣言構文を使用して指定することができます。 ただし、このアプローチでは手動で SQL ステートメントを記述する必要があり、単調でエラーが発生しやすい状況となるおそれがあります。 さいわい、データ ソースの構成ウィザードには、ビューのテーブルから列を指定する画面を使用して、INSERT
、UPDATE
、DELETE
の各ステートメントを自動的に生成するオプションが用意されています。
この自動生成オプションを見ていきましょう。 DetailsView を InsertUpdateDelete.aspx
のデザイナーに追加し、その ID
プロパティを ManageProducts
に設定します。 次に、DetailsView のスマート タグで、新しいデータ ソースの作成を選択し、ManageProductsDataSource
という名前の SqlDataSource を作成します。
図 6: ManageProductsDataSource
という名前の新しい SqlDataSource を作成する (クリックするとフルサイズの画像が表示されます)
データ ソースの構成ウィザードで、NORTHWINDConnectionString
接続文字列の使用を選択し、[次へ] をクリックします。 [SELECT ステートメントの構成] 画面で、[テーブルまたはビューから列を指定する] ラジオ ボタンを選択し、ドロップダウンリストから Products
テーブルを選択します。 チェックボックス リストの ProductID
、ProductName
、UnitPrice
、Discontinued
の列を選択します。
図 7: Products
テーブルを使用して、ProductID
、ProductName
、UnitPrice
、Discontinued
の列を返す (クリックするとフルサイズの画像が表示されます)
選択したテーブルと列に基づいて、INSERT
、UPDATE
、DELETE
の各ステートメントを自動生成するには、[詳細] ボタンをクリックし、[INSERT
、UPDATE
、DELETE
ステートメントを生成する] チェックボックスをオンにします。
図 8: [INSERT
、UPDATE
、DELETE
ステートメントを生成する] チェックボックスをオンにする
[INSERT
、UPDATE
、DELETE
ステートメントを生成する] チェックボックスは、選択したテーブルに主キーがあり、返される列の一覧にその主キー列が含まれている場合にのみオンにできます。 [オプティミスティック同時実行制御を使用する] チェックボックスは、[INSERT
、UPDATE
、DELETE
ステートメントを生成する] チェックボックスがオンになると選択可能になり、結果の UPDATE
と DELETE
のステートメントの WHERE
句を拡張してオプティミスティック同時実行制御を提供します。 ここでは、このチェックボックスはオフのままにしておきます。次のチュートリアルで、SqlDataSource コントロールを使用したオプティミスティック同時実行制御を取り上げます。
[INSERT
、UPDATE
、DELETE
ステートメントを生成する] チェックボックスをオンにした後、[OK] をクリックして [SELECT ステートメントの構成] 画面に戻り、[次へ] をクリックしてから [完了] をクリックしてデータ ソースの構成ウィザードを完了します。 ウィザードが完了すると、Visual Studio によって、DetailsView の ProductID
、ProductName
、UnitPrice
列に BoundFields が追加され、Discontinued
列に CheckBoxField が追加されます。 DetailsView のスマート タグで、[ページングを有効にする] オプションをオンにして、このページにアクセスするユーザーが製品全体を閲覧できるようにします。 DetailsView の Width
と Height
のプロパティもクリアにします。
スマート タグでは、[挿入を有効にする]、[編集を有効にする]、[削除を有効にする] のオプションが利用できるようになっています。 これは、次の宣言構文に示すように、SqlDataSource で、その InsertCommand
、UpdateCommand
、DeleteCommand
の値が含まれているためです。
<asp:DetailsView ID="ManageProducts" runat="server" AllowPaging="True"
AutoGenerateRows="False" DataKeyNames="ProductID"
DataSourceID="ManageProductsDataSource" EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductID" HeaderText="ProductID"
InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="ProductName" HeaderText="ProductName"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
<asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource ID="ManageProductsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
DeleteCommand=
"DELETE FROM [Products] WHERE [ProductID] = @ProductID"
InsertCommand=
"INSERT INTO [Products] ([ProductName], [UnitPrice], [Discontinued])
VALUES (@ProductName, @UnitPrice, @Discontinued)"
SelectCommand=
"SELECT [ProductID], [ProductName], [UnitPrice], [Discontinued]
FROM [Products]"
UpdateCommand=
"UPDATE [Products] SET [ProductName] = @ProductName,
[UnitPrice] = @UnitPrice, [Discontinued] = @Discontinued
WHERE [ProductID] = @ProductID">
<DeleteParameters>
<asp:Parameter Name="ProductID" Type="Int32" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Name="ProductName" Type="String" />
<asp:Parameter Name="UnitPrice" Type="Decimal" />
<asp:Parameter Name="Discontinued" Type="Boolean" />
<asp:Parameter Name="ProductID" Type="Int32" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="ProductName" Type="String" />
<asp:Parameter Name="UnitPrice" Type="Decimal" />
<asp:Parameter Name="Discontinued" Type="Boolean" />
</InsertParameters>
</asp:SqlDataSource>
SqlDataSource コントロールで、その InsertCommand
、UpdateCommand
、DeleteCommand
プロパティにどのように値が自動設定されているかに注意してください。 InsertCommand
と UpdateCommand
のプロパティで参照される列のセットは、SELECT
ステートメントの列に基づいています。 つまり、InsertCommand
と UpdateCommand
に "すべて" の Products 列が含まれるのではなく、SelectCommand
に指定されている列のみが存在しています (ProductID
は除きます。これは IDENTITY
列であり、その値は編集時に変更できず、挿入時に自動的に割り当てられるものであるため、省略されます)。 さらに、InsertCommand
、UpdateCommand
、DeleteCommand
のプロパティ内の各パラメーターには、InsertParameters
、UpdateParameters
、DeleteParameters
のコレクションの対応するパラメーターがあります。
DetailsView のデータ変更機能を有効にするには、スマート タグで [挿入を有効にする]、[編集を有効にする]、[削除を有効にする] の各オプションをオンにします。 これにより、ShowInsertButton
、ShowEditButton
、ShowDeleteButton
のプロパティが True
に設定されている CommandField が追加されます。
ブラウザーでページにアクセスして、DetailsView に [編集]、[削除]、[新規] ボタンがあることを確認します。 [編集] ボタンをクリックすると、DetailsView が編集モードになり、ReadOnly
プロパティが False
(既定値) に設定されている各 BoundField がテキストボックスとして表示され、CheckBoxField がチェックボックスとして表示されます。
図 9: DetailsView のデフォルトの編集インターフェイス (クリックするとフルサイズの画像が表示されます)
同様に、現在選択されている製品を削除することも、新しい製品をシステムに追加することもできます。 InsertCommand
ステートメントは ProductName
、UnitPrice
、Discontinued
の列でのみ機能するため、他の列には、NULL
または挿入時にデータベースによって割り当てられる既定値が割り当てられます。 ObjectDataSource の場合と同様に、InsertCommand
では、NULL
を許可せず、既定値を持たないデータベース テーブル列がない場合、INSERT
ステートメントを実行しようとすると SQL エラーが発生します。
Note
DetailsView の挿入インターフェイスと編集インターフェイスには、カスタマイズや検証の機能が一切ありません。 検証コントロールの追加やインターフェイスのカスタマイズを行うには、BoundFields を TemplateFields に変換する必要があります。 詳細については、「編集および挿入インターフェイスに検証コントロールを追加する」と「データ変更インターフェイスをカスタマイズする」のチュートリアルを参照してください。
また、更新と削除の場合、DetailsView では現在の製品の DataKey
値が使用されることにも注意してください。この値は DataKeyNames
プロパティが構成されている場合にのみ存在します。 編集や削除を行っても効果がないように見える場合は、DataKeyNames
プロパティが設定されているかを確認してください。
SQL ステートメントの自動生成に関する制限事項
[INSERT
、UPDATE
、DELETE
ステートメントを生成する] オプションはテーブルから列を選択する場合にのみ使用できるため、より複雑なクエリの場合は、ステップ 1 で行ったように自身で INSERT
、UPDATE
、DELETE
ステートメントを記述する必要があります。 一般に、SQL SELECT
ステートメントでは、表示目的で 1 つ以上のルックアップ テーブルからデータを取得するのに JOIN
を使用します (製品情報を表示する場合に Categories
テーブルの CategoryName
フィールドを取得するなど)。 同時に、ユーザーがコア テーブル (この場合は Products
) のデータを編集、更新、挿入できるようにした方がよいでしょう。
INSERT
、UPDATE
、DELETE
のステートメントを手動で入力するような場合に、次の時間節約のヒントを検討してみてください。 最初に、SqlDataSource を Products
テーブルからデータをプルするように設定します。 データ ソースの構成ウィザードの [テーブルまたはビューから列を指定する] 画面を使用して、INSERT
、UPDATE
、DELETE
のステートメントを自動生成できるようにします。 次に、ウィザードの完了後、プロパティ ウィンドウで SelectQuery の構成を選択します (または、データ ソースの構成ウィザードに戻り、[カスタム SQL ステートメントまたはストアド プロシージャを指定する] オプションを使用します)。 次に、JOIN
構文を含むように SELECT
ステートメントを更新します。 この手法により、SQL ステートメントの自動生成による時間節約のメリットを提供するとともに、SELECT
ステートメントのより柔軟なカスタマイズを可能にします。
INSERT
、UPDATE
、DELETE
ステートメントの自動生成が抱えるもう 1 つの制限は、INSERT
と UPDATE
のステートメントの列が SELECT
ステートメントによって返される列に基づくということです。 更新または挿入するフィールドが設定より多く、または少なく必要になる場合があるかもしれません。 たとえば、ステップ 2 の例では、UnitPrice
BoundField を読み取り専用にしたい場合があります。 その場合は、それを UpdateCommand
に含めないようにする必要があります。 または、GridView に表示されないテーブル フィールドの値を設定したい場合があります。 たとえば、新しいレコードを追加するときに、QuantityPerUnit
値を TODO に設定する必要がある場合などです。
このようなカスタマイズが必要な場合には、プロパティ ウィンドウ、ウィザードの [カスタム SQL ステートメントまたはストアド プロシージャを指定する] オプション、宣言構文などを使用して、手動で行う必要があります。
Note
対応するフィールドがデータ Web コントロールにないパラメーターを追加する場合は、何らかの方法で、これらのパラメーター値に値を割り当てる必要があることに注意してください。 これらの値は、InsertCommand
または UpdateCommand
で直接ハードコーディングする、事前定義ソース (クエリ文字列、セッション状態、ページ上の Web コントロールなど) から、または前のチュートリアルで述べられていたように、プログラムによる割り当て、などの方法で割り当てることができます。
まとめ
データ Web コントロールで組み込みの挿入、編集、削除の機能を利用するには、バインドされているデータ ソース コントロールでこのような機能を提供する必要があります。 SqlDataSource の場合、これは、INSERT
、UPDATE
、DELETE
SQL ステートメントを InsertCommand
、UpdateCommand
、DeleteCommand
プロパティに割り当てる必要があることを意味します。 これらのプロパティおよび対応するパラメーター コレクションは、手動で追加することも、データ ソースの構成ウィザードを使用して自動生成することもできます。 このチュートリアルでは、両方の手法を取り上げました。
「オプティミスティック同時実行制御の実装」に関するチュートリアルで、ObjectDataSource でのオプティミスティック同時実行制御の使用について取り上げました。 SqlDataSource コントロールでも、オプティミスティック同時実行制御のサポートが提供されます。 ステップ 2 で述べたように、INSERT
、UPDATE
、DELETE
ステートメントを自動生成する場合、ウィザードには [オプティミスティック同時実行制御を使用する] オプションが用意されています。 次のチュートリアルで説明するとおり、SqlDataSource でオプティミスティック同時実行制御を使用すると、UPDATE
と DELETE
のステートメントの WHERE
句が変更され、データが最後にページに表示されてから他の列の値が変更されていないことが確認されます。
プログラミングに満足!
著者について
7 冊の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジに取り組んでいます。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。