次の方法で共有


SqlDataSource でデータを挿入、更新、削除する (C#)

スコット・ミッチェル著

PDF をダウンロードする

前のチュートリアルでは、ObjectDataSource コントロールがデータの挿入、更新、および削除を許可する方法について学習しました。 SqlDataSource コントロールは同じ操作をサポートしますが、その方法は異なります。このチュートリアルでは、データを挿入、更新、削除するように SqlDataSource を構成する方法について説明します。

イントロダクション

挿入、更新、および削除の概要」で説明したように、GridView コントロールには組み込みの更新および削除機能が用意されていますが、DetailsView コントロールと FormView コントロールには、編集および削除機能と共にサポートの挿入が含まれます。 これらのデータ変更機能は、コード行を記述する必要なく、データ ソース コントロールに直接接続できます。 ObjectDataSource を使用して、GridView、DetailsView、および FormView コントロールで挿入、更新、削除を容易に行う方法を調べた「挿入、更新、および削除の概要」。 または、ObjectDataSource の代わりに SqlDataSource を使用することもできます。

挿入、更新、削除をサポートするには、ObjectDataSource を使用して、挿入、更新、または削除アクションを実行するために呼び出すオブジェクト レイヤー メソッドを指定する必要があることを思い出してください。 SqlDataSource では、INSERTUPDATE、および DELETE の SQL ステートメント (またはストアド プロシージャ) を提供して実行する必要があります。 このチュートリアルで説明するように、これらのステートメントは手動で作成することも、SqlDataSource のデータ ソースの構成ウィザードで自動的に生成することもできます。

GridView、DetailsView、および FormView コントロールの挿入、編集、削除の機能については既に説明しているので、このチュートリアルでは、これらの操作をサポートするように SqlDataSource コントロールを構成することに重点を置きます。 GridView、DetailsView、および FormView 内でこれらの機能の実装をブラッシュアップする必要がある場合は、「挿入、更新、および削除の概要」から始めて、データの編集、挿入 、および削除のチュートリアルに戻ります。

手順 1: INSERT、UPDATE、および DELETE ステートメントを指定する

過去 2 つのチュートリアルで説明したように、SqlDataSource コントロールからデータを取得するには、次の 2 つのプロパティを設定する必要があります。

  1. ConnectionString: クエリを送信するデータベースを指定します。
  2. SelectCommand: 結果を返すために実行するアドホック SQL ステートメントまたはストアド プロシージャ名を指定します。

パラメーター SelectCommand 値の場合、パラメーター値は SqlDataSource の SelectParameters コレクションを介して指定され、ハードコーディングされた値、共通パラメーター ソース値 (querystring フィールド、セッション変数、Web コントロール値など) を含めたり、プログラムで割り当てたりすることができます。 SqlDataSource コントロールの Select() メソッドがプログラムによって、またはデータ Web コントロールから自動的に呼び出されると、データベースへの接続が確立されると、パラメーター値がクエリに割り当てられ、コマンドがデータベースに切り替えられます。 結果は、コントロールの DataSourceMode プロパティの値に応じて、DataSet または DataReader として返されます。

データの選択に加えて、SqlDataSource コントロールを使用して、SQL ステートメントの INSERTUPDATE、および DELETE を同じ方法で指定することで、データの挿入、更新、削除を行うことができます。 InsertCommandUpdateCommandDeleteCommandの各プロパティを、実行するINSERTUPDATEDELETE SQL ステートメントに割り当てるだけです。 ステートメントにパラメーターがある場合 (ほとんどの場合と同様)、それらを InsertParametersUpdateParameters、および DeleteParameters コレクションに含めます。

InsertCommandUpdateCommand、またはDeleteCommandの値が指定されると、対応するデータ Web コントロールのスマート タグの [挿入の有効化]、[編集の有効化]、または [削除の有効化] オプションが使用できるようになります。 これを説明するために、「Querying.aspxを使用したデータのクエリ」チュートリアルで作成した ページの例を見て、削除機能を含むように拡張します。

まず、InsertUpdateDelete.aspx フォルダーからQuerying.aspxページとSqlDataSource ページを開きます。 Querying.aspx ページのデザイナーで、最初の例 (ProductsDataSource コントロールとGridView1 コントロール) から SqlDataSource と GridView を選択します。 2 つのコントロールを選択したら、[編集] メニューに移動し、[コピー] を選択します (または Ctrl キーを押しながら C キーを押します)。 次に、 InsertUpdateDelete.aspx のデザイナーに移動し、コントロールを貼り付けます。 2 つのコントロールを InsertUpdateDelete.aspxに移動したら、ブラウザーでページをテストします。 ProductID データベース テーブル内のすべてのレコードのProductNameUnitPrice、およびProducts列の値が表示されます。

すべての製品が ProductID 別に一覧表示されます

図 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 プロパティを選択すると、省略記号のセットが表示されます。

DeleteQuery プロパティが選択された ProductsDataSource プロパティ ウィンドウを示すスクリーンショット。

図 2: [プロパティ] ウィンドウから DeleteQuery プロパティを選択する

SqlDataSource には DeleteQuery プロパティがありません。 代わりに、DeleteQuery は DeleteCommand プロパティと DeleteParameters プロパティの組み合わせであり、デザイナーでウィンドウを表示する場合にのみ [プロパティ] ウィンドウに一覧表示されます。 [ソース] ビューで [プロパティ] ウィンドウを見ている場合は、代わりに DeleteCommand プロパティが表示されます。

DeleteQuery プロパティの省略記号をクリックして、[コマンドおよびパラメーター エディター] ダイアログ ボックスを表示します (図 3 を参照)。 このダイアログ ボックスから、 DELETE SQL ステートメントを指定し、パラメーターを指定できます。 DELETE コマンド テキスト ボックスに次のクエリを入力します (手動で、または必要に応じてクエリ ビルダーを使用します)。

DELETE FROM Products
WHERE ProductID = @ProductID

次に、[パラメーターの更新] ボタンをクリックして、 @ProductID パラメーターを以下のパラメーターの一覧に追加します。

Screenshot showing the Command and Parameter Editor window with the <span class= 。 />

図 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 に示すように、ブラウザーからページにアクセスすると、[削除] ボタンが含まれます。 一部の製品を削除して、このページをテストします。

各 GridView 行に [削除] ボタンが含まれるようになりました

図 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 コントロールの 挿入、更新、および削除に関連するイベント のチェーンの詳細については、「挿入、更新、および削除に関連するイベントの確認」チュートリアルを参照してください。

GridView で [削除] ボタンをクリックすると、SqlDataSource s Delete() メソッドが呼び出されます

図 5: GridView の [削除] ボタンをクリックすると、SqlDataSource の Delete() メソッドが呼び出される

手順 2: INSERT、UPDATE、および DELETE ステートメントを自動的に生成する

手順 1 で調べたように、 INSERTUPDATEDELETE SQL ステートメントは、[プロパティ] ウィンドウまたはコントロールの宣言型構文を使用して指定できます。 ただし、このアプローチでは、手動で SQL ステートメントを記述する必要があります。これは単調でエラーが発生しやすい可能性があります。 さいわい、データ ソースの構成ウィザードには、[ビューのテーブルから列を指定する] 画面を使用するときに、 INSERTUPDATE、および DELETE ステートメントを自動的に生成するオプションが用意されています。

この自動生成オプションを調べてみましょう。 InsertUpdateDelete.aspxのデザイナーに DetailsView を追加し、そのIDプロパティを ManageProducts に設定します。 次に、DetailsView のスマート タグから、新しいデータ ソースを作成し、 ManageProductsDataSourceという名前の SqlDataSource を作成することを選択します。

ManageProductsDataSource という名前の新しい SqlDataSource を作成する

図 6: ManageProductsDataSource という名前の新しい SqlDataSource を作成する (フルサイズの画像を表示する をクリックします)

データ ソースの構成ウィザードで、 NORTHWINDConnectionString 接続文字列を使用することを選択し、[次へ] をクリックします。 [ステートメントの選択] 画面で、[テーブルまたはビューから列を指定する] ラジオボタンを選択した状態を維持し、ドロップダウンリストから Products テーブルを選びます。 チェック ボックスの一覧から、 ProductIDProductNameUnitPrice、および Discontinued 列を選択します。

Products テーブルを使用して、ProductID、ProductName、UnitPrice、および廃止された列を返します。

図 7: Products テーブルを使用して、 ProductIDProductNameUnitPrice、および Discontinued 列を返します (フルサイズの画像を表示する をクリックします)。

選択したテーブルと列に基づいて INSERTUPDATE、および DELETE ステートメントを自動的に生成するには、[詳細設定] ボタンをクリックし、[ INSERTUPDATE、および DELETE ステートメントを生成する] チェック ボックスをオンにします。

[INSERT ステートメント、UPDATE ステートメント、DELETE ステートメントの生成] チェック ボックスをオンにする

図 8: INSERT, UPDATE, および DELETE ステートメントを生成するチェックボックスをオンにする

[ INSERTUPDATE、および DELETE ステートメントの生成] チェック ボックスは、選択したテーブルに主キーがあり、主キー列 (または列) が返される列の一覧に含まれている場合にのみチェックできます。 INSERTUPDATEDELETE ステートメントの生成] チェック ボックスがオンになると、[オプティミスティック コンカレンシーを使用する] チェック ボックスが選択できるようになります。このチェック ボックスを選択すると、結果として生成されるWHEREおよびUPDATEステートメントのDELETE句が拡張され、オプティミスティック コンカレンシー制御が提供されます。 ここでは、このチェック ボックスをオフのままにします。次のチュートリアルでは、SqlDataSource コントロールを使用してオプティミスティック コンカレンシーを調べます。

[ INSERTUPDATE、および DELETE ステートメントの生成] チェック ボックスをオンにした後、[OK] をクリックして [ステートメントの選択の構成] 画面に戻り、[次へ] をクリックし、[完了] をクリックしてデータ ソースの構成ウィザードを完了します。 ウィザードが完了すると、Visual Studio によって、 ProductIDProductName、および UnitPrice 列の DetailsView に BoundFields が追加され、 Discontinued 列に CheckBoxField が追加されます。 DetailsView のスマート タグから、[ページングを有効にする] オプションをオンにして、このページにアクセスするユーザーが製品を順に確認できるようにします。 DetailsView の Width プロパティと Height プロパティもクリアします。

スマート タグには、[挿入を有効にする]、[編集を有効にする]、[削除を有効にする] のオプションがあります。 これは、次の宣言構文に示すように、SqlDataSource には InsertCommandUpdateCommand、および 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 コントロールの InsertCommandUpdateCommand、および DeleteCommand プロパティに対して値が自動的に設定されていることに注意してください。 InsertCommandおよびUpdateCommandプロパティで参照される列のセットは、SELECT ステートメントの列に基づいています。 つまり、InsertCommandUpdateCommand Products 列を含めるのではなく、SelectCommandで指定された列のみが存在します (ProductIDが少なくなります。これは、編集時に値を変更できず、挿入時に自動的に割り当てられるIDENTITYであるため省略されます)。 さらに、 InsertCommandUpdateCommand、および DeleteCommand プロパティの各パラメーターには、 InsertParametersUpdateParameters、および DeleteParameters コレクションに対応するパラメーターがあります。

DetailsView のデータ変更機能を有効にするには、スマート タグの [挿入を有効にする]、[編集を有効にする]、[削除を有効にする] オプションをオンにします。 これにより、 ShowInsertButtonShowEditButton、および ShowDeleteButton プロパティが trueに設定された CommandField が追加されます。

ブラウザーでページにアクセスし、DetailsView に含まれる [編集]、[削除]、および [新規] ボタンをメモします。 [編集] ボタンをクリックすると、DetailsView が編集モードになり、 ReadOnly プロパティが TextBox として false (既定値) に設定されている各 BoundField が表示され、CheckBoxField がチェック ボックスとして表示されます。

DetailsView の既定の編集インターフェイス

図 9: DetailsView の既定の編集インターフェイス (フルサイズの画像を表示する をクリックします)

同様に、現在選択されている製品を削除することも、新しい製品をシステムに追加することもできます。 InsertCommand ステートメントは、ProductNameUnitPrice、およびDiscontinued列でのみ機能するため、他の列には、挿入時にデータベースによって割り当てられたNULLまたは既定値が割り当てられます。 ObjectDataSource と同様に、 InsertCommandNULL を許可せず、既定値がないデータベース テーブル列がない場合は、 INSERT ステートメントを実行しようとしたときに SQL エラーが発生します。

DetailsView の挿入および編集インターフェイスには、あらゆる種類のカスタマイズや検証がありません。 検証コントロールを追加したり、インターフェイスをカスタマイズしたりするには、BoundFields を TemplateFields に変換する必要があります。 詳細については、 インターフェイスの編集および挿入に検証コントロールを追加する チュートリアルと データ変更インターフェイスのカスタマイズ に関するチュートリアルを参照してください。

また、更新と削除の場合、DetailsView では現在の製品の DataKey 値が使用されることに注意してください。これは、 DataKeyNames プロパティが構成されている場合にのみ存在します。 編集または削除しても効果がないように見える場合は、 DataKeyNames プロパティが設定されていることを確認します。

SQL ステートメントの自動生成に関する制限事項

[ INSERTUPDATE、および DELETE ステートメントの生成] オプションはテーブルから列を選択する場合にのみ使用できるため、より複雑なクエリの場合は、手順 1 で行ったように独自の INSERTUPDATE、および DELETE ステートメントを記述する必要があります。 一般に、SQL SELECT ステートメントでは、表示目的で 1 つ以上のルックアップ テーブルからデータを取り戻すために JOIN を使用します (製品情報を表示するときに Categories テーブルの CategoryName フィールドを戻すなど)。 同時に、ユーザーがコア テーブル (この場合は Products) にデータを編集、更新、または挿入できるようにすることができます。

INSERTUPDATE、およびDELETEステートメントは手動で入力できますが、次の時間節約のヒントを検討してください。 Products テーブルからのみデータを取得するように、SqlDataSource を最初に設定します。 INSERTUPDATE、およびDELETEステートメントを自動的に生成できるように、データ ソースの構成ウィザードのテーブルまたはビュー画面から列を指定します。 次に、ウィザードが完了したら、[プロパティ] ウィンドウから SelectQuery を構成することを選択します (または、データ ソースの構成ウィザードに戻りますが、[カスタム SQL ステートメントまたはストアド プロシージャの指定] オプションを使用します)。 次に、 SELECT ステートメントを更新して、 JOIN 構文を含めます。 この手法は、自動的に生成される SQL ステートメントの時間節約の利点を提供し、よりカスタマイズされた SELECT ステートメントを可能にします。

INSERTUPDATE、およびDELETEステートメントを自動的に生成するもう 1 つの制限事項は、INSERT ステートメントと UPDATE ステートメント内の列が、SELECT ステートメントによって返される列に基づいているということです。 ただし、フィールドをより多くまたは少なく更新または挿入する必要があるかもしれません。 たとえば、手順 2 の例では、BoundField UnitPrice を読み取り専用にしたい場合があります。 その場合、UpdateCommandには表示されるべきではありません。 または、GridView に表示されないテーブル フィールドの値を設定することもできます。 たとえば、新しいレコードを追加するときに、 QuantityPerUnit 値を TODO に設定する必要があります。

このようなカスタマイズが必要な場合は、[プロパティ] ウィンドウ、ウィザードの [カスタム SQL ステートメントまたはストアド プロシージャの指定] オプション、または宣言構文を使用して手動で行う必要があります。

データ Web コントロールに対応するフィールドがないパラメーターを追加する場合は、これらのパラメーター値に何らかの方法で値を割り当てる必要があることに注意してください。 これらの値は、 InsertCommand または UpdateCommandで直接ハードコーディングできます。事前に定義されたソース (クエリ文字列、セッション状態、ページ上の Web コントロールなど) から取得することも、前のチュートリアルで説明したようにプログラムで割り当てることもできます。

概要

データ Web コントロールが組み込みの挿入、編集、削除の機能を利用するには、バインドされているデータ ソース コントロールでこのような機能を提供する必要があります。 SqlDataSource の場合、これは、 INSERTUPDATE、および DELETE SQL ステートメントを、 InsertCommandUpdateCommand、および DeleteCommand の各プロパティに割り当てる必要があることを意味します。 これらのプロパティおよび対応するパラメーター コレクションは、手動で追加することも、データ ソースの構成ウィザードを使用して自動的に生成することもできます。 このチュートリアルでは、両方の手法を調べました。

オプティミスティック コンカレンシーの実装に関するチュートリアルで、ObjectDataSource で オプティミスティック コンカレンシー を使用して調べました。 SqlDataSource コントロールでは、オプティミスティック コンカレンシーのサポートも提供されます。 手順 2 で説明したように、 INSERTUPDATE、および 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で連絡できます。