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