次の方法で共有


JOIN を使用するように TableAdapter を更新する (VB)

スコット・ミッチェル著

PDF をダウンロードする

データベースを操作する場合、複数のテーブルに分散するデータを要求するのが一般的です。 2 つの異なるテーブルからデータを取得するには、相関サブクエリまたは JOIN 操作を使用します。 このチュートリアルでは、メイン クエリに JOIN を含む TableAdapter を作成する方法を確認する前に、相関サブクエリと JOIN 構文を比較します。

イントロダクション

リレーショナル データベースでは、作業に関心があるデータは、多くの場合、複数のテーブルに分散されます。 たとえば、製品情報を表示する場合は、各製品の対応するカテゴリと仕入先の名前を一覧表示する必要があります。 ProductsテーブルにはCategoryID値とSupplierID値がありますが、実際のカテゴリ名と仕入先名はそれぞれCategoriesテーブルとSuppliersテーブルにあります。

別の関連テーブルから情報を取得するには、 相関サブクエリ または JOINを使用します。 相関サブクエリは、外側のクエリ内の列を参照する入れ子になった SELECT クエリです。 たとえば、「 データ アクセス層の作成 」チュートリアルでは、 ProductsTableAdapter のメイン クエリで 2 つの相関サブクエリを使用して、各製品のカテゴリ名と仕入先名を返しました。 JOINは、2 つの異なるテーブルから関連する行をマージする SQL コンストラクトです。 JOINチュートリアルのを使用して、各製品と共にカテゴリ情報を表示しました。

TableAdapters で JOIN s を使用することを控えた理由は、TableAdapter ウィザードで対応する INSERTUPDATE、および DELETE ステートメントを自動生成する制限があるためです。 具体的には、TableAdapter のメイン クエリに JOIN が含まれている場合、TableAdapter は、その InsertCommandUpdateCommand、および DeleteCommand プロパティのアドホック SQL ステートメントまたはストアド プロシージャを自動作成できません。

このチュートリアルでは、メイン クエリにJOINを含む TableAdapter を作成する方法を調べる前に、相関サブクエリとJOINを簡単に比較して比較します。

相関サブクエリとJOIN の比較とコントラスト

最初のチュートリアルで作成したProductsTableAdapterは、Northwind DataSet の中で相関サブクエリを使用して各製品の対応するカテゴリとサプライヤー名を取得します。 ProductsTableAdapterのメイン クエリを次に示します。

SELECT ProductID, ProductName, SupplierID, CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = 
            Products.CategoryID) as CategoryName, 
       (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = 
            Products.SupplierID) as SupplierName
FROM Products

関連付けられた 2 つのサブクエリ ((SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID)(SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID)) は、外側の SELECT ステートメントの列リストの追加列として製品ごとに 1 つの値を返すSELECTクエリです。

または、 JOIN を使用して、各製品のサプライヤーとカテゴリ名を返すことができます。 次のクエリは、上記と同じ出力を返しますが、サブクエリの代わりに JOIN s を使用します。

SELECT ProductID, ProductName, Products.SupplierID, Products.CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       Categories.CategoryName, 
       Suppliers.CompanyName as SupplierName
FROM Products
    LEFT JOIN Categories ON
        Categories.CategoryID = Products.CategoryID
    LEFT JOIN Suppliers ON
        Suppliers.SupplierID = Products.SupplierID

JOINは、あるテーブルのレコードを、いくつかの条件に基づいて別のテーブルのレコードとマージします。 たとえば、上記のクエリでは、 LEFT JOIN Categories ON Categories.CategoryID = Products.CategoryID は、各製品レコードを、 CategoryID 値が製品の CategoryID 値と一致するカテゴリ レコードとマージするように SQL Server に指示します。 マージされた結果により、各製品の対応するカテゴリ フィールド ( CategoryName など) を操作できます。

JOIN は、リレーショナル データベースからデータに対してクエリを実行する場合に一般的に使用されます。 JOIN構文を初めて使用する場合や、その使用方法を少しブラッシュアップする必要がある場合は、W3 SchoolsSQL Join チュートリアルをお勧めします。 また、JOIN Fundamentals と Subquery Fundamentals セクションも読む価値があります。

JOINサブクエリと相関サブクエリの両方を使用して他のテーブルから関連データを取得できるため、多くの開発者は頭を悩み、使用する方法を疑問に思っています。 私が話したすべてのSQLの達人は、SQL Serverがほぼ同じ実行計画を生成するため、パフォーマンスは本当に重要ではありません。 その後、彼らのアドバイスは、あなたとあなたのチームが最も快適な技術を使用することです。 このアドバイスを与えた後、すぐにこれらの専門家が相関サブクエリよりもJOINを好むことを表現している点に注目に値します。

型指定されたデータセットを使用してデータ アクセス層を構築する場合、サブクエリを使用する場合はツールの方が適切に機能します。 特に、TableAdapter ウィザードでは、メイン クエリにINSERTが含まれている場合、対応するUPDATEDELETE、およびJOINステートメントは自動生成されませんが、関連付けられたサブクエリが使用されている場合は、これらのステートメントが自動生成されます。

この欠点を調べるには、 ~/App_Code/DAL フォルダーに一時的な型指定された DataSet を作成します。 TableAdapter 構成ウィザードで、アドホック SQL ステートメントの使用を選択し、次の SELECT クエリを入力します (図 1 を参照)。

SELECT ProductID, ProductName, Products.SupplierID, Products.CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       Categories.CategoryName, 
       Suppliers.CompanyName as SupplierName
FROM Products
    LEFT JOIN Categories ON
        Categories.CategoryID = Products.CategoryID
    LEFT JOIN Suppliers ON
        Suppliers.SupplierID = Products.SupplierID

JOIN を含むクエリが入力された TableAdaptor 構成ウィザード ウィンドウを示すスクリーンショット。

図 1: JOIN を含むメイン クエリを入力します (フルサイズの画像を表示する をクリックします)。

既定では、TableAdapter はメイン クエリに基づいて INSERTUPDATE、および DELETE ステートメントを自動的に作成します。 [詳細設定] ボタンをクリックすると、この機能が有効になっていることがわかります。 この設定にもかかわらず、TableAdapter は、メイン クエリにINSERTが含まれているため、UPDATEDELETE、およびJOINステートメントを作成できません。

[挿入、更新、および削除ステートメントの生成] チェック ボックスがオンの [詳細オプション] ウィンドウを示すスクリーンショット。

図 2: JOIN を含むメイン クエリを入力する

[完了] をクリックして、ウィザードを完了します。 この時点で、DataSet のデザイナーには、 SELECT クエリの列リストに返される各フィールドの列を含む DataTable を含む単一の TableAdapter が含まれます。 これには、図 3 に示すように、 CategoryNameSupplierNameが含まれます。

DataTable には、列リストに返される各フィールドの列が含まれます

図 3: DataTable には、列リストに返される各フィールドの列が含まれています

DataTable には適切な列が含まれていますが、TableAdapter には InsertCommandUpdateCommand、および DeleteCommand プロパティの値がありません。 これを確認するには、デザイナーで TableAdapter をクリックし、[プロパティ] ウィンドウに移動します。 ここでは、 InsertCommandUpdateCommand、および DeleteCommand のプロパティが (None) に設定されていることがわかります。

InsertCommand、UpdateCommand、DeleteCommand の各プロパティは 、(None) に設定されます。

図 4: InsertCommandUpdateCommand、および DeleteCommand のプロパティが (なし) に設定されている (フルサイズの画像を表示する をクリックします)。

この欠点を回避するには、[プロパティ] ウィンドウを使用して、 InsertCommandUpdateCommand、および DeleteCommand プロパティの SQL ステートメントとパラメーターを手動で指定します。 または、tableAdapter のメイン クエリを構成して、を含JOINすることもできます。 これにより、 INSERTUPDATE、および DELETE ステートメントを自動生成できます。 ウィザードが完了したら、[プロパティ] ウィンドウから TableAdapter の SelectCommand を手動で更新し、 JOIN 構文が含まれるようにすることができます。

この方法は機能しますが、アドホック SQL クエリを使用する場合は非常に脆弱です。TableAdapter のメイン クエリがウィザードを使用して再構成されるたびに、自動生成された INSERTUPDATE、および DELETE ステートメントが再作成されるためです。 つまり、TableAdapter を右クリックし、コンテキスト メニューから [構成] を選択し、ウィザードをもう一度完了すると、後で行ったすべてのカスタマイズが失われます。

TableAdapter の自動生成された INSERTUPDATE、および DELETE ステートメントの脆弱性は、幸いにもアドホック SQL ステートメントに限定されます。 TableAdapter でストアド プロシージャが使用されている場合は、ストアド プロシージャの SelectCommandInsertCommandUpdateCommand、または DeleteCommand をカスタマイズし、ストアド プロシージャが変更されることを心配せずに TableAdapter 構成ウィザードを再実行できます。

次のいくつかの手順では、TableAdapter を作成します。最初は、対応する挿入、更新、および削除ストアド プロシージャが自動生成されるように、 JOIN を省略するメイン クエリを使用します。 次に、関連テーブルから追加の列を返すSelectCommandを使用するように、JOINを更新します。 最後に、対応するビジネス ロジック レイヤー クラスを作成し、ASP.NET Web ページで TableAdapter を使用する方法を示します。

手順 1: 簡略化されたメイン クエリを使用して TableAdapter を作成する

このチュートリアルでは、Employees DataSet の NorthwindWithSprocs テーブルに TableAdapter と厳密に型指定された DataTable を追加します。 Employeesテーブルには、従業員の上司のReportsToを指定したEmployeeIDフィールドが含まれています。 たとえば、従業員の Anne Dodsworth の ReportTo 値は 5 で、これはスティーブン・ブキャナンの EmployeeID です。 その結果、アンはマネージャーのスティーブンに報告します。 各従業員の ReportsTo 値を報告するだけでなく、マネージャーの名前を取得することもできます。 これは、 JOINを使用して実現できます。 ただし、TableAdapter を最初に作成するときに JOIN を使用すると、ウィザードで対応する挿入、更新、削除の機能が自動的に生成されなくなります。 したがって、まず、メイン クエリに JOIN が含まれていない TableAdapter を作成します。 次に、手順 2 では、メイン クエリ ストアド プロシージャを更新して、 JOINを使用してマネージャーの名前を取得します。

まず、NorthwindWithSprocs フォルダーの ~/App_Code/DAL DataSet を開きます。 デザイナーを右クリックし、コンテキスト メニューから [追加] オプションを選択し、[TableAdapter] メニュー項目を選択します。 これにより TableAdapter 構成ウィザードが起動します。 図 5 に示すように、ウィザードで新しいストアド プロシージャを作成し、[次へ] をクリックします。 TableAdapter ウィザードから新しいストアド プロシージャを作成する方法については、「 Typed DataSet s TableAdapters の新しいストアド プロシージャの作成 」チュートリアルを参照してください。

[新しいストアド プロシージャの作成] オプションを選択する

図 5: 新しいストアド プロシージャの作成オプションを選択します (フルサイズの画像を表示する をクリックします)。

TableAdapter のメイン クエリには、次の SELECT ステートメントを使用します。

SELECT EmployeeID, LastName, FirstName, Title, HireDate, ReportsTo, Country
FROM Employees

このクエリには JOIN が含まれていないため、TableAdapter ウィザードは、対応する INSERTUPDATE、および DELETE ステートメントを含むストアド プロシージャと、メイン クエリを実行するためのストアド プロシージャを自動的に作成します。

次の手順では、TableAdapter のストアド プロシージャに名前を付けます。 図 6 に示すように、 Employees_SelectEmployees_InsertEmployees_Update、および Employees_Deleteの名前を使用します。

TableAdapter のストアド プロシージャに名前を付けます

図 6: TableAdapter のストアド プロシージャに名前を付ける (フルサイズの画像を表示する をクリックします)

最後の手順では、TableAdapter のメソッドに名前を付けるプロンプトが表示されます。 メソッド名として FillGetEmployees を使用します。 [データベースに直接更新を送信するメソッドを作成する (GenerateDBDirectMethods)] チェック ボックスをオンのままにしておいてください。

TableAdapter のメソッド Fill と GetEmployees に名前を付ける

図 7: TableAdapter メソッドに FillGetEmployees の名前を付ける (フルサイズの画像を表示する をクリックします)

ウィザードが完了したら、少し時間を取ってデータベース内のストアド プロシージャを調べます。 Employees_SelectEmployees_InsertEmployees_UpdateEmployees_Deleteの 4 つの新しいものが表示されます。 次に、作成した EmployeesDataTableEmployeesTableAdapter を確認します。 DataTable には、メイン クエリによって返される各フィールドの列が含まれています。 TableAdapter をクリックし、[プロパティ] ウィンドウに移動します。 InsertCommandUpdateCommand、およびDeleteCommandのプロパティが、対応するストアド プロシージャを呼び出すために正しく構成されていることがわかります。

TableAdapter には、挿入、更新、および削除の機能が含まれています

図 8: TableAdapter には、挿入、更新、および削除の機能が含まれています (フルサイズの画像を表示する をクリックします)。

挿入、更新、および削除ストアド プロシージャが自動的に作成され、 InsertCommandUpdateCommand、および DeleteCommand プロパティが正しく構成されたので、各従業員のマネージャーに関する追加情報を返すように SelectCommand のストアド プロシージャをカスタマイズする準備ができました。 具体的には、 Employees_Select ストアド プロシージャを更新して JOIN を使用し、マネージャーの FirstNameLastName の値を返す必要があります。 ストアド プロシージャが更新された後、これらの追加の列が含まれるように DataTable を更新する必要があります。 手順 2 と 3 でこれら 2 つのタスクに取り組みます。

手順 2: ストアド プロシージャをカスタマイズして、パラメータを含めるJOIN

まず、サーバー エクスプローラーに移動し、Northwind データベースのストアド プロシージャ フォルダーをドリルダウンし、 Employees_Select ストアド プロシージャを開きます。 このストアド プロシージャが表示されない場合は、[ストアド プロシージャ] フォルダーを右クリックし、[最新の情報に更新] を選択します。 ストアド プロシージャを更新して、 LEFT JOIN を使用してマネージャーの名と姓を返すようにします。

SELECT Employees.EmployeeID, Employees.LastName, 
       Employees.FirstName, Employees.Title, 
       Employees.HireDate, Employees.ReportsTo, 
       Employees.Country,
       Manager.FirstName as ManagerFirstName, 
       Manager.LastName as ManagerLastName
FROM Employees
    LEFT JOIN Employees AS Manager ON
        Employees.ReportsTo = Manager.EmployeeID

SELECTステートメントを更新した後、[ファイル] メニューに移動し、[Employees_Select保存] を選択して変更を保存します。 または、ツール バーの [保存] アイコンをクリックするか、Ctrl + S キーを押します。 変更を保存した後、サーバー エクスプローラーで Employees_Select ストアド プロシージャを右クリックし、[実行] を選択します。 これにより、ストアド プロシージャが実行され、その結果が [出力] ウィンドウに表示されます (図 9 を参照)。

ストアド プロシージャの結果が出力ウィンドウに表示される

図 9: ストアド プロシージャの結果が出力ウィンドウに表示されます (フルサイズの画像を表示する をクリックします)。

手順 3: DataTable の列を更新する

この時点で、 Employees_Select ストアド プロシージャは ManagerFirstName 値と ManagerLastName 値を返しますが、 EmployeesDataTable にこれらの列がありません。 これらの不足している列は、次の 2 つの方法のいずれかで DataTable に追加できます。

  • 手動 - DataSet デザイナーで DataTable を右クリックし、[追加] メニューから [列] を選択します。 その後、列に名前を付け、それに応じてプロパティを設定できます。
  • 自動的 に - TableAdapter 構成ウィザードは、 SelectCommand ストアド プロシージャによって返されるフィールドを反映するように DataTable の列を更新します。 アドホック SQL ステートメントを使用すると、InsertCommandUpdateCommandが含まれるようになったため、DeleteCommandSelectCommand、およびJOINプロパティも削除されます。 ただし、ストアド プロシージャを使用する場合、これらのコマンド プロパティはそのまま残ります。

前のチュートリアルでは、マスター/詳細を含む DataTable 列を手動で追加する方法について説明しました。これには、 詳細データ リストを含むマスター レコードの箇条書きリストの使用ファイルのアップロードが含まれます。このプロセスについては、次のチュートリアルでもう一度詳しく説明します。 ただし、このチュートリアルでは、TableAdapter 構成ウィザードを使用して自動アプローチを使用します。

まず、 EmployeesTableAdapter を右クリックし、コンテキスト メニューから [構成] を選択します。 これにより、TableAdapter 構成ウィザードが表示され、選択、挿入、更新、削除に使用されるストアド プロシージャと、戻り値とパラメーター (存在する場合) が一覧表示されます。 図 10 は、このウィザードを示しています。 ここでは、 Employees_Select ストアド プロシージャが ManagerFirstName フィールドと ManagerLastName フィールドを返すようになったことがわかります。

Employees_Select ストアド プロシージャの更新された列の一覧が表示されるウィザード

図 10: ウィザードは、 Employees_Select ストアド プロシージャの更新された列の一覧を表示します (フルサイズの画像を表示する をクリックします)。

[完了] をクリックしてウィザードを終了します。 DataSet デザイナーに戻ると、 EmployeesDataTable には、 ManagerFirstNameManagerLastNameの 2 つの列が追加されています。

EmployeesDataTable に 2 つの新しい列が含まれている

図 11: EmployeesDataTable には 2 つの新しい列が含まれています (フルサイズの画像を表示する をクリックします)。

更新された Employees_Select ストアド プロシージャが有効であり、TableAdapter の挿入、更新、削除機能がまだ機能していることを示すために、ユーザーが従業員を表示および削除できる Web ページを作成しましょう。 ただし、このようなページを作成する前に、まず、 NorthwindWithSprocs DataSet の従業員と連携するための新しいクラスをビジネス ロジック レイヤーに作成する必要があります。 手順 4 では、 EmployeesBLLWithSprocs クラスを作成します。 手順 5 では、ASP.NET ページからこのクラスを使用します。

手順 4: ビジネス ロジック 層の実装

~/App_Code/BLLという名前のEmployeesBLLWithSprocs.vb フォルダーに新しいクラス ファイルを作成します。 このクラスは、既存の EmployeesBLL クラスのセマンティクスを模倣します。この新しいクラスでは提供されるメソッドが少なく、NorthwindWithSprocs DataSet ではなく Northwind DataSet が使用されます。 EmployeesBLLWithSprocs クラスに次のコードを追加します。

Imports NorthwindWithSprocsTableAdapters
<System.ComponentModel.DataObject()> _
Public Class EmployeesBLLWithSprocs
    Private _employeesAdapter As EmployeesTableAdapter = Nothing
    Protected ReadOnly Property Adapter() As EmployeesTableAdapter
        Get
            If _employeesAdapter Is Nothing Then
                _employeesAdapter = New EmployeesTableAdapter()
            End If
            Return _employeesAdapter
        End Get
    End Property
    <System.ComponentModel.DataObjectMethodAttribute _
        (System.ComponentModel.DataObjectMethodType.Select, True)> _
    Public Function GetEmployees() As NorthwindWithSprocs.EmployeesDataTable
        Return Adapter.GetEmployees()
    End Function
    <System.ComponentModel.DataObjectMethodAttribute _
        (System.ComponentModel.DataObjectMethodType.Delete, True)> _
    Public Function DeleteEmployee(ByVal employeeID As Integer) As Boolean
        Dim rowsAffected = Adapter.Delete(employeeID)
        'Return true if precisely one row was deleted, otherwise false
        Return rowsAffected = 1
    End Function
End Class

EmployeesBLLWithSprocs クラス s Adapter プロパティは、NorthwindWithSprocs DataSet のEmployeesTableAdapterのインスタンスを返します。 これは、クラスの GetEmployees メソッドと DeleteEmployee メソッドによって使用されます。 GetEmployees メソッドは、EmployeesTableAdapterの対応するGetEmployees メソッドを呼び出します。これにより、Employees_Select ストアド プロシージャが呼び出され、その結果がEmployeeDataTableに設定されます。 DeleteEmployee メソッドは同様に、EmployeesTableAdapter ストアド プロシージャを呼び出すDeleteEmployees_Delete メソッドを呼び出します。

手順 5: プレゼンテーション層のデータを操作する

EmployeesBLLWithSprocs クラスが完成したら、ASP.NET ページを使用して従業員データを操作する準備ができました。 JOINs.aspx フォルダーのAdvancedDAL ページを開き、ツールボックスからデザイナーに GridView をドラッグし、そのIDプロパティをEmployeesに設定します。 次に、GridView のスマート タグから、グリッドを EmployeesDataSource という名前の新しい ObjectDataSource コントロールにバインドします。

EmployeesBLLWithSprocs クラスを使用するように ObjectDataSource を構成し、[SELECT] タブと [DELETE] タブから、GetEmployeesメソッドと DeleteEmployee メソッドがドロップダウン リストから選択されていることを確認します。 [完了] をクリックして ObjectDataSource の構成を完了します。

EmployeesBLLWithSprocs クラスを使用するように ObjectDataSource を構成する

図 12: EmployeesBLLWithSprocs クラスを使用するように ObjectDataSource を構成する (フルサイズの画像を表示する をクリックします)。

ObjectDataSource で GetEmployees メソッドと DeleteEmployee メソッドを使用する

図 13: ObjectDataSource に GetEmployees メソッドと DeleteEmployee メソッドを使用させる (フルサイズの画像を表示する をクリックします)

Visual Studio は、 EmployeesDataTable の各列の GridView に BoundField を追加します。 TitleLastNameFirstNameManagerFirstNameManagerLastNameを除き、これらの BoundFields をすべて削除し、最後の 4 つの BoundFields のHeaderTextプロパティの名前をそれぞれ姓、名、マネージャー名、およびマネージャーの姓に変更します。

ユーザーがこのページから従業員を削除できるようにするには、2 つの操作を行う必要があります。 最初に、GridView に対して、スマート タグから [削除を有効にする] オプションをオンにして削除機能を提供するように指示します。 次に、ObjectDataSource の OldValuesParameterFormatString プロパティを、ObjectDataSource ウィザード (original_{0}) によって設定された値から既定値 ({0}) に変更します。 これらの変更を行った後、GridView と ObjectDataSource の宣言型マークアップは次のようになります。

<asp:GridView ID="Employees" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="EmployeeID" DataSourceID="EmployeesDataSource">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" />
        <asp:BoundField DataField="Title" 
            HeaderText="Title" 
            SortExpression="Title" />
        <asp:BoundField DataField="LastName" 
            HeaderText="Last Name" 
            SortExpression="LastName" />
        <asp:BoundField DataField="FirstName" 
            HeaderText="First Name" 
            SortExpression="FirstName" />
        <asp:BoundField DataField="ManagerFirstName" 
            HeaderText="Manager's First Name" 
            SortExpression="ManagerFirstName" />
        <asp:BoundField DataField="ManagerLastName" 
            HeaderText="Manager's Last Name" 
            SortExpression="ManagerLastName" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="EmployeesDataSource" runat="server" 
    DeleteMethod="DeleteEmployee" OldValuesParameterFormatString="{0}" 
    SelectMethod="GetEmployees" TypeName="EmployeesBLLWithSprocs">
    <DeleteParameters>
        <asp:Parameter Name="employeeID" Type="Int32" />
    </DeleteParameters>
</asp:ObjectDataSource>

ブラウザーからページにアクセスして、ページをテストします。 図 14 に示すように、ページには各従業員とその上司の名前が一覧表示されます (あると仮定)。

Employees_Select ストアド プロシージャの JOIN は、マネージャーの名前を返します。

図 14: JOIN ストアド プロシージャのEmployees_Selectは、マネージャーの名前を返します (フルサイズの画像を表示する をクリックします)。

[削除] ボタンをクリックすると、削除のためのワークフローが開始され、Employees_Delete ストアド プロシージャの実行に至ります。 ただし、ストアド プロシージャで試行された DELETE ステートメントは、外部キー制約違反のために失敗します (図 15 を参照)。 具体的には、各従業員が Orders テーブルに 1 つ以上のレコードを持っており、削除が失敗します。

対応する注文がある従業員を削除すると、外部キー制約違反が発生する

図 15: 対応する注文を持つ従業員を削除すると、外部キー制約違反が発生します (フルサイズの画像を表示する をクリックします)。

従業員の削除を許可するには、次の手順を実行します。

私はこれを読者の練習として残します。

概要

リレーショナル データベースを使用する場合、クエリは複数の関連テーブルからデータをプルするのが一般的です。 相関サブクエリと JOIN は、クエリ内の関連テーブルからデータにアクセスするための 2 つの異なる手法を提供します。 前のチュートリアルでは、TableAdapter は、INSERTに関連するクエリのUPDATEDELETE、およびJOINステートメントを自動生成できないため、相関サブクエリを最もよく使用しました。 これらの値は手動で指定できますが、アドホック SQL ステートメントを使用する場合、TableAdapter 構成ウィザードが完了すると、カスタマイズが上書きされます。

幸いなことに、ストアド プロシージャを使用して作成された TableAdapters は、アドホック SQL ステートメントを使用して作成されたものと同じ脆弱性を受けません。 そのため、ストアド プロシージャを使用するときにメイン クエリで JOIN を使用する TableAdapter を作成できます。 このチュートリアルでは、このような TableAdapter を作成する方法について説明しました。 まず、TableAdapter のメイン クエリに対して JOINのない SELECT クエリを使用して、対応する挿入、更新、および削除ストアド プロシージャが自動的に作成されるようにしました。 TableAdapter の初期構成が完了したら、SelectCommandを使用するようにJOIN ストアド プロシージャを拡張し、TableAdapter 構成ウィザードを再実行してEmployeesDataTableの列を更新しました。

TableAdapter 構成ウィザードを再実行すると、EmployeesDataTable ストアド プロシージャによって返されるデータ フィールドを反映するように、Employees_Select列が自動的に更新されます。 または、これらの列を DataTable に手動で追加することもできます。 次のチュートリアルでは、DataTable に列を手動で追加する方法について説明します。

プログラミングに満足!

著者について

7 冊の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジを使用しています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズ・ティーチ・セルフ ASP.NET 24時間で2.0です。 彼には mitchell@4GuysFromRolla.comで連絡できます。

特別な感謝

このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、ヒルトン ガイズナウ、David Suru、テレサ マーフィーでした。 今後の MSDN の記事を確認することに関心がありますか? その場合は、mitchell@4GuysFromRolla.comにメッセージを送ってください。