ビューを使用したデータ変更

テーブル内のデータを変更する場合と同じように、UPDATE、INSERT、DELETE の各ステートメントを使用するか、または bcp ユーティリティと BULK INSERT ステートメントを使用することにより、基になるベース テーブルのデータをビューを使用して変更できます。ただし、更新するビューに次の制限事項が適用されます。テーブルには適用されません。

注意

次の制限事項には、パーティション ビューに適用されないものがあります。また、INSTEAD OF トリガーを使用して適用された更新内容にはどの制限事項も適用されません。詳細については、このトピックの「ビューを使用してデータを変更するためのその他のオプション」を参照してください。

  • UPDATE、INSERT、DELETE ステートメントなどの変更で、1 つのベース テーブルのみの列を参照している。

  • ビューにある変更対象の列が、テーブルの列内にある基になるデータを直接参照している。ただし次のような方法では、列は派生しません。

    • 集計関数 (AVG、COUNT、SUM、MIN、MAX、GROUPING、STDEV、STDEVP、VAR、および VARP)。

    • 計算。他の列を使用した式から列を計算することはできません。set 演算子 (UNION、UNION ALL、CROSSJOIN、EXCEPT、および INTERSECT) を使用して作成された列は、計算を意味します。また、更新することはできません。

  • 変更対象の列は、GROUP BY、HAVING、または DISTINCT の各句による影響を受けない。

  • WITH CHECK OPTION を指定している場合、ビューの select_statement では TOP を使用できない。

以前の制限は、ビュー自体に適用されるのと同様に、ビューの FROM 句のサブクエリにも適用されます。通常は、SQL Server では、ビュー定義からベース テーブルへの変更を正確に追跡できる必要があります。たとえば、次のビューは更新できません。

USE AdventureWorks2008R2;
GO
CREATE VIEW Sales.TotalSalesContacts
AS
    SELECT p.LastName, 
           SUM(o.TotalDue) AS TotalSales
    FROM Sales.SalesOrderHeader AS o, Person.Person AS p
    WHERE p.BusinessEntityID = o.CustomerID
    GROUP BY LastName;

TotalSalesContacts の LastName 列は GROUP BY 句の影響を受けているため、その列に対する変更は許可されません。同じ姓のインスタンスが複数存在する場合、SQL Server では、どのインスタンスに対して UPDATE、INSERT、または DELETE を実行する必要があるのかを判断できません。同様に、TotalSalesContacts の TotalSales 列を変更しようとすると、この列は集計関数から派生した列なのでエラーが返されます。SQL Server では、この列を SalesOrderHeader ベース テーブルに直接トレースすることができません。

さらに、次のガイドラインにも従う必要があります。

  • ビューの定義で WITH CHECK OPTION 句を使用する場合、ビューに対して実行されるすべてのデータ変更ステートメントは、ビューを定義する SELECT ステートメントの基準に従う必要があります。WITH CHECK OPTION 句を使用した場合、行がビューに表示されなくなるような変更は実行できません。このような変更は取り消され、エラーが表示されることになります。

  • INSERT ステートメントでは、基になるテーブル内の NULL 値を許容しない列で、かつ DEFAULT 定義のない列の値を指定する必要があります。

  • 基になるテーブルの列で変更されたデータは、NULL 値を許容するかどうか、制約、DEFAULT 定義など、その列に課せられた制限に従う必要があります。たとえば、行を削除する場合、関連するテーブルのすべての FOREIGN KEY 制約が満たされない限り、正常に削除できません。

  • 分散パーティション ビュー (リモート ビュー) は、キーセット ドリブン カーソルを使用して更新することができません。この制限は、ビュー自体ではなく、基になるテーブル上でカーソルを宣言することにより解決できます。

  • パーティション ビューへのデータの一括インポートは、bcp、または BULK INSERT および INSERT ... SELECT * FROM OPENROWSET(BULK...) ステートメントのいずれでもサポートされません。しかし、INSERT ステートメントを使用することにより、パーティション ビューに複数の行を挿入できます。詳細については、「ビューからのデータの一括エクスポートとビューへのデータの一括インポート」を参照してください。

  • READTEXT ステートメントおよび WRITETEXT ステートメントは、ビューの text、ntext、または image のいずれかの型の列と共に使用することはできません。

ビューを使用してデータを変更するためのその他のオプション

このトピックのこれまでに説明した制約によってビューから直接データを変更できない場合は、次の方法を試してください。

  • INSERT、UPDATE、および DELETE の各ステートメントをサポートするロジックを持つ INSTEAD OF トリガーを使用します。詳細については、「INSTEAD OF トリガのデザイン」を参照してください。

  • 1 つ以上のメンバー テーブルを変更する更新可能なパーティション ビューを使用します。詳細については、「パーティション ビューの作成」を参照してください。

ビューを使用してデータを追加するには

ビューを使用してデータを変更するには

ビューを使用してデータを削除するには

関連項目

概念