次の方法で共有


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

作成者: Scott Mitchell

PDF のダウンロード

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

はじめに

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

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

Note

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 として返されます。

データの選択と併せて、ほぼ同様の方法で INSERTUPDATEDELETE の各 SQL ステートメントを指定することで、SqlDataSource コントロールを使用して、データの挿入、更新、削除を行うことができます。 単純に InsertCommandUpdateCommandDeleteCommand のプロパティに INSERTUPDATEDELETE の各 SQL ステートメントを割り当てて実行します。 ステートメントにパラメーターがある場合 (ほとんどの場合と同様)、パラメーターを InsertParametersUpdateParametersDeleteParameters のコレクションに含めます。

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

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

All of the Products are Listed, Ordered by ProductID

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

Screenshot showing the ProductsDataSource Properties window with the DeleteQuery property selected.

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

Note

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=@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 に示すように、ブラウザーからページにアクセスすると、[削除] ボタンが表示されています。 いくつかの製品を削除して、このページをテストしてみましょう。

Each GridView Row Now Includes a Delete Button

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

Clicking the Delete Button in the GridView Invokes the SqlDataSource s Delete() Method

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

ステップ 2: INSERTUPDATEDELETE の各ステートメントを自動的に生成する

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

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

Create a New SqlDataSource Named ManageProductsDataSource

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

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

Using the Products Table, Return the ProductID, ProductName, UnitPrice, and Discontinued Columns

図 7: Products テーブルを使用して、ProductIDProductNameUnitPriceDiscontinued の列を返す (クリックするとフルサイズの画像が表示されます)

選択したテーブルと列に基づいて、INSERTUPDATEDELETE の各ステートメントを自動生成するには、[詳細] ボタンをクリックし、[INSERTUPDATEDELETE ステートメントを生成する] チェックボックスをオンにします。

Check the Generate INSERT, UPDATE, and DELETE statements Checkbox

図 8: [INSERTUPDATEDELETE ステートメントを生成する] チェックボックスをオンにする

[INSERTUPDATEDELETE ステートメントを生成する] チェックボックスは、選択したテーブルに主キーがあり、返される列の一覧にその主キー列が含まれている場合にのみオンにできます。 [オプティミスティック同時実行制御を使用する] チェックボックスは、[INSERTUPDATEDELETE ステートメントを生成する] チェックボックスがオンになると選択可能になり、結果の UPDATEDELETE のステートメントの WHERE 句を拡張してオプティミスティック同時実行制御を提供します。 ここでは、このチェックボックスはオフのままにしておきます。次のチュートリアルで、SqlDataSource コントロールを使用したオプティミスティック同時実行制御を取り上げます。

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

スマート タグでは、[挿入を有効にする]、[編集を有効にする]、[削除を有効にする] のオプションが利用できるようになっています。 これは、次の宣言構文に示すように、SqlDataSource で、その InsertCommandUpdateCommandDeleteCommand の値が含まれているためです。

<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 コントロールで、その InsertCommandUpdateCommandDeleteCommand プロパティにどのように値が自動設定されているかに注意してください。 InsertCommandUpdateCommand のプロパティで参照される列のセットは、SELECT ステートメントの列に基づいています。 つまり、InsertCommandUpdateCommand に "すべて" の Products 列が含まれるのではなく、SelectCommand に指定されている列のみが存在しています (ProductID は除きます。これは IDENTITYであり、その値は編集時に変更できず、挿入時に自動的に割り当てられるものであるため、省略されます)。 さらに、InsertCommandUpdateCommandDeleteCommand のプロパティ内の各パラメーターには、InsertParametersUpdateParametersDeleteParameters のコレクションの対応するパラメーターがあります。

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

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

The DetailsView s Default Editing Interface

図 9: DetailsView のデフォルトの編集インターフェイス (クリックするとフルサイズの画像が表示されます)

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

Note

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

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

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

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

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

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

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

Note

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

まとめ

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

オプティミスティック同時実行制御の実装」に関するチュートリアルで、ObjectDataSource でのオプティミスティック同時実行制御の使用について取り上げました。 SqlDataSource コントロールでも、オプティミスティック同時実行制御のサポートが提供されます。 ステップ 2 で述べたように、INSERTUPDATEDELETE ステートメントを自動生成する場合、ウィザードには [オプティミスティック同時実行制御を使用する] オプションが用意されています。 次のチュートリアルで説明するとおり、SqlDataSource でオプティミスティック同時実行制御を使用すると、UPDATEDELETE のステートメントの WHERE 句が変更され、データが最後にページに表示されてから他の列の値が変更されていないことが確認されます。

プログラミングに満足!

著者について

7 冊の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジに取り組んでいます。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。