前のチュートリアルでは、ObjectDataSource コントロールがデータの挿入、更新、および削除を許可する方法について学習しました。 SqlDataSource コントロールは同じ操作をサポートしますが、その方法は異なります。このチュートリアルでは、データを挿入、更新、削除するように SqlDataSource を構成する方法について説明します。
イントロダクション
「 挿入、更新、および削除の概要」で説明したように、GridView コントロールには組み込みの更新および削除機能が用意されていますが、DetailsView コントロールと FormView コントロールには、編集および削除機能と共にサポートの挿入が含まれます。 これらのデータ変更機能は、コード行を記述する必要なく、データ ソース コントロールに直接接続できます。 ObjectDataSource を使用して、GridView、DetailsView、および FormView コントロールで挿入、更新、削除を容易に行う方法を調べた「挿入、更新、および削除の概要」。 または、ObjectDataSource の代わりに SqlDataSource を使用することもできます。
挿入、更新、削除をサポートするには、ObjectDataSource を使用して、挿入、更新、または削除アクションを実行するために呼び出すオブジェクト レイヤー メソッドを指定する必要があることを思い出してください。 SqlDataSource では、INSERT
、UPDATE
、および DELETE
の SQL ステートメント (またはストアド プロシージャ) を提供して実行する必要があります。 このチュートリアルで説明するように、これらのステートメントは手動で作成することも、SqlDataSource のデータ ソースの構成ウィザードで自動的に生成することもできます。
注
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 として返されます。
データの選択に加えて、SqlDataSource コントロールを使用して、SQL ステートメントの INSERT
、 UPDATE
、および DELETE
を同じ方法で指定することで、データの挿入、更新、削除を行うことができます。
InsertCommand
、UpdateCommand
、DeleteCommand
の各プロパティを、実行するINSERT
、UPDATE
、DELETE
SQL ステートメントに割り当てるだけです。 ステートメントにパラメーターがある場合 (ほとんどの場合と同様)、それらを InsertParameters
、 UpdateParameters
、および DeleteParameters
コレクションに含めます。
InsertCommand
、UpdateCommand
、またはDeleteCommand
の値が指定されると、対応するデータ Web コントロールのスマート タグの [挿入の有効化]、[編集の有効化]、または [削除の有効化] オプションが使用できるようになります。 これを説明するために、「Querying.aspx
を使用したデータのクエリ」チュートリアルで作成した ページの例を見て、削除機能を含むように拡張します。
まず、InsertUpdateDelete.aspx
フォルダーからQuerying.aspx
ページとSqlDataSource
ページを開きます。
Querying.aspx
ページのデザイナーで、最初の例 (ProductsDataSource
コントロールとGridView1
コントロール) から SqlDataSource と GridView を選択します。 2 つのコントロールを選択したら、[編集] メニューに移動し、[コピー] を選択します (または Ctrl キーを押しながら C キーを押します)。 次に、 InsertUpdateDelete.aspx
のデザイナーに移動し、コントロールを貼り付けます。 2 つのコントロールを InsertUpdateDelete.aspx
に移動したら、ブラウザーでページをテストします。
ProductID
データベース テーブル内のすべてのレコードのProductName
、UnitPrice
、およびProducts
列の値が表示されます。
図 1: すべての製品が一覧表示され、 ProductID
順に並べ替えられます (フルサイズの画像を表示する をクリックします)。
SqlDataSource の DeleteCommand プロパティと DeleteParameters プロパティの追加
この時点で、 Products
テーブルからすべてのレコードを返す SqlDataSource と、このデータをレンダリングする GridView があります。 この例を拡張して、ユーザーが GridView を介して製品を削除できるようにすることが目標です。 これを実現するには、SqlDataSource コントロールの DeleteCommand
プロパティと DeleteParameters
プロパティの値を指定し、削除をサポートするように GridView を構成する必要があります。
DeleteCommand
プロパティとDeleteParameters
プロパティは、さまざまな方法で指定できます。
- 宣言構文を使用する
- デザイナーの [プロパティ] ウィンドウから
- データ ソースの構成ウィザードの [カスタム SQL ステートメントまたはストアド プロシージャの指定] 画面から
- [データ ソースの構成] ウィザードの [ビューのテーブルから列を指定する] 画面の [詳細設定] ボタンを使用すると、
DELETE
プロパティとDeleteCommand
プロパティで使用されるDeleteParameters
SQL ステートメントとパラメーター コレクションが実際に自動的に生成されます。
手順 2 で DELETE
ステートメントを自動的に作成する方法について説明します。 ここでは、デザイナーで [プロパティ] ウィンドウを使用しますが、データ ソースの構成ウィザードまたは宣言型構文オプションも同様に機能します。
InsertUpdateDelete.aspx
のデザイナーで、ProductsDataSource
SqlDataSource をクリックし、[プロパティ] ウィンドウを表示します ([表示] メニューから [プロパティ] ウィンドウを選択するか、F4 キーを押します)。 DeleteQuery プロパティを選択すると、省略記号のセットが表示されます。
図 2: [プロパティ] ウィンドウから DeleteQuery プロパティを選択する
注
SqlDataSource には DeleteQuery プロパティがありません。 代わりに、DeleteQuery は DeleteCommand
プロパティと DeleteParameters
プロパティの組み合わせであり、デザイナーでウィンドウを表示する場合にのみ [プロパティ] ウィンドウに一覧表示されます。 [ソース] ビューで [プロパティ] ウィンドウを見ている場合は、代わりに DeleteCommand
プロパティが表示されます。
DeleteQuery プロパティの省略記号をクリックして、[コマンドおよびパラメーター エディター] ダイアログ ボックスを表示します (図 3 を参照)。 このダイアログ ボックスから、 DELETE
SQL ステートメントを指定し、パラメーターを指定できます。
DELETE
コマンド テキスト ボックスに次のクエリを入力します (手動で、または必要に応じてクエリ ビルダーを使用します)。
DELETE FROM Products
WHERE ProductID = @ProductID
次に、[パラメーターの更新] ボタンをクリックして、 @ProductID
パラメーターを以下のパラメーターの一覧に追加します。
図 3: プロパティ ウィンドウから DeleteQuery プロパティを選択します (フルサイズの画像を表示する をクリックします)
このパラメーターには値を指定 しないでください (パラメーター ソースは None のままにします)。 GridView に削除のサポートを追加すると、GridView は、削除ボタンがクリックされた行の DataKeys
コレクションの値を使用して、このパラメーター値を自動的に指定します。
注
DELETE
クエリで使用されるパラメーター名は、GridView、DetailsView、または FormView の値の名前と同じであるDataKeyNames
。 つまり、products テーブルの主キー列名 (したがって、GridView の DataKeyNames 値) がDELETE
されているため、@ProductID
ステートメントのパラメーターは意図的に@ID
(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
という名前の Parameter オブジェクトに注意してください。
削除用の GridView の構成
DeleteCommand
プロパティが追加され、GridView のスマート タグに [削除の有効化] オプションが含まれるようになりました。 先に進み、このチェックボックスをオンにします。 「 挿入、更新、および削除の概要」で説明したように、これにより、GridView は、その ShowDeleteButton
プロパティが true
に設定された CommandField を追加します。 図 4 に示すように、ブラウザーからページにアクセスすると、[削除] ボタンが含まれます。 一部の製品を削除して、このページをテストします。
図 4: 各 GridView 行に削除ボタンが含まれるようになりました (フルサイズの画像を表示する をクリックします)
[削除] ボタンをクリックするとポストバックが発生し、GridView は ProductID
パラメーターに[削除] ボタンがクリックされた行の DataKeys
コレクション値の値を割り当て、SqlDataSource の Delete()
メソッドを呼び出します。 その後、SqlDataSource コントロールはデータベースに接続し、 DELETE
ステートメントを実行します。 その後、GridView は SqlDataSource に再バインドし、現在の製品セットを取得して表示します (削除されたレコードは含まれなくなりました)。
注
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
ステートメントを自動的に生成するオプションが用意されています。
この自動生成オプションを調べてみましょう。
InsertUpdateDelete.aspx
のデザイナーに DetailsView を追加し、そのID
プロパティを ManageProducts
に設定します。 次に、DetailsView のスマート タグから、新しいデータ ソースを作成し、 ManageProductsDataSource
という名前の SqlDataSource を作成することを選択します。
図 6: ManageProductsDataSource
という名前の新しい SqlDataSource を作成する (フルサイズの画像を表示する をクリックします)
データ ソースの構成ウィザードで、 NORTHWINDConnectionString
接続文字列を使用することを選択し、[次へ] をクリックします。 [ステートメントの選択] 画面で、[テーブルまたはビューから列を指定する] ラジオボタンを選択した状態を維持し、ドロップダウンリストから 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
ステートメントの生成] チェック ボックスがオンになると、[オプティミスティック コンカレンシーを使用する] チェック ボックスが選択できるようになります。このチェック ボックスを選択すると、結果として生成されるWHERE
およびUPDATE
ステートメントのDELETE
句が拡張され、オプティミスティック コンカレンシー制御が提供されます。 ここでは、このチェック ボックスをオフのままにします。次のチュートリアルでは、SqlDataSource コントロールを使用してオプティミスティック コンカレンシーを調べます。
[ INSERT
、 UPDATE
、および DELETE
ステートメントの生成] チェック ボックスをオンにした後、[OK] をクリックして [ステートメントの選択の構成] 画面に戻り、[次へ] をクリックし、[完了] をクリックしてデータ ソースの構成ウィザードを完了します。 ウィザードが完了すると、Visual Studio によって、 ProductID
、 ProductName
、および UnitPrice
列の DetailsView に 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
プロパティが TextBox として false
(既定値) に設定されている各 BoundField が表示され、CheckBoxField がチェック ボックスとして表示されます。
図 9: DetailsView の既定の編集インターフェイス (フルサイズの画像を表示する をクリックします)
同様に、現在選択されている製品を削除することも、新しい製品をシステムに追加することもできます。
InsertCommand
ステートメントは、ProductName
、UnitPrice
、およびDiscontinued
列でのみ機能するため、他の列には、挿入時にデータベースによって割り当てられたNULL
または既定値が割り当てられます。 ObjectDataSource と同様に、 InsertCommand
に NULL
を許可せず、既定値がないデータベース テーブル列がない場合は、 INSERT
ステートメントを実行しようとしたときに SQL エラーが発生します。
注
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
ステートメントは手動で入力できますが、次の時間節約のヒントを検討してください。
Products
テーブルからのみデータを取得するように、SqlDataSource を最初に設定します。
INSERT
、UPDATE
、およびDELETE
ステートメントを自動的に生成できるように、データ ソースの構成ウィザードのテーブルまたはビュー画面から列を指定します。 次に、ウィザードが完了したら、[プロパティ] ウィンドウから SelectQuery を構成することを選択します (または、データ ソースの構成ウィザードに戻りますが、[カスタム SQL ステートメントまたはストアド プロシージャの指定] オプションを使用します)。 次に、 SELECT
ステートメントを更新して、 JOIN
構文を含めます。 この手法は、自動的に生成される SQL ステートメントの時間節約の利点を提供し、よりカスタマイズされた SELECT
ステートメントを可能にします。
INSERT
、UPDATE
、およびDELETE
ステートメントを自動的に生成するもう 1 つの制限事項は、INSERT
ステートメントと UPDATE
ステートメント内の列が、SELECT
ステートメントによって返される列に基づいているということです。 ただし、フィールドをより多くまたは少なく更新または挿入する必要があるかもしれません。 たとえば、手順 2 の例では、BoundField UnitPrice
を読み取り専用にしたい場合があります。 その場合、UpdateCommand
には表示されるべきではありません。 または、GridView に表示されないテーブル フィールドの値を設定することもできます。 たとえば、新しいレコードを追加するときに、 QuantityPerUnit
値を TODO に設定する必要があります。
このようなカスタマイズが必要な場合は、[プロパティ] ウィンドウ、ウィザードの [カスタム SQL ステートメントまたはストアド プロシージャの指定] オプション、または宣言構文を使用して手動で行う必要があります。
注
データ Web コントロールに対応するフィールドがないパラメーターを追加する場合は、これらのパラメーター値に何らかの方法で値を割り当てる必要があることに注意してください。 これらの値は、 InsertCommand
または UpdateCommand
で直接ハードコーディングできます。事前に定義されたソース (クエリ文字列、セッション状態、ページ上の Web コントロールなど) から取得することも、前のチュートリアルで説明したようにプログラムで割り当てることもできます。
概要
データ Web コントロールが組み込みの挿入、編集、削除の機能を利用するには、バインドされているデータ ソース コントロールでこのような機能を提供する必要があります。 SqlDataSource の場合、これは、 INSERT
、 UPDATE
、および DELETE
SQL ステートメントを、 InsertCommand
、 UpdateCommand
、および DeleteCommand
の各プロパティに割り当てる必要があることを意味します。 これらのプロパティおよび対応するパラメーター コレクションは、手動で追加することも、データ ソースの構成ウィザードを使用して自動的に生成することもできます。 このチュートリアルでは、両方の手法を調べました。
オプティミスティック コンカレンシーの実装に関するチュートリアルで、ObjectDataSource で オプティミスティック コンカレンシー を使用して調べました。 SqlDataSource コントロールでは、オプティミスティック コンカレンシーのサポートも提供されます。 手順 2 で説明したように、 INSERT
、 UPDATE
、および DELETE
ステートメントを自動的に生成すると、ウィザードには [オプティミスティック コンカレンシーを使用する] オプションが用意されています。 次のチュートリアルで説明するように、SqlDataSource でオプティミスティック コンカレンシーを使用すると、WHERE
ステートメントと UPDATE
ステートメントのDELETE
句が変更され、データが最後にページに表示されてから他の列の値が変更されていないことが確認されます。
プログラミングに満足!
著者について
7 冊の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジを使用しています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズ・ティーチ・セルフ ASP.NET 24時間で2.0です。 彼には mitchell@4GuysFromRolla.comで連絡できます。