DELETE の使用による行の削除

DELETE ステートメントは、テーブルやビューの 1 つ以上の行を削除する場合に使用します。

DELETE 構文を簡略化すると、次のような形式になります。

DELETE table_or_view

FROM table_sources

WHERE search_condition

パラメータ table_or_view には、行を削除するテーブルまたはビューを指定します。WHERE 検索条件の制限を満たす table_or_view 内のすべての行が削除されます。WHERE 句を指定しなかった場合は、table_or_view 内のすべての行が削除されます。FROM 句では、追加のテーブルやビュー、および table_or_view. から削除する行を限定するための WHERE 句検索条件の述語で使用できる結合条件を指定します。FROM 句で指定したテーブルから行が削除されることはありません。table_or_view で指定したテーブルからのみ削除されます。

すべての行が削除されても、テーブルはデータベース内に残ります。DELETE ステートメントでは、テーブルの行だけが削除されます。つまり、DROP TABLE ステートメントを使用して、データベースからテーブルを削除する必要があります。

ヒープからの行の削除

ヒープから行が削除されるとき、データベース エンジンではこの操作で行ロックまたはページ ロックを行うことがあります。その結果、削除操作によって空になったページは、ヒープに割り当てられたままになります。空のページの割り当てが解除されないと、関連する領域はデータベースの他のオブジェクトから再利用できません。

ヒープ内の行を削除してページの割り当てを解除するには、次のうちいずれかの方法を使用します。

  • DELETE ステートメントで TABLOCK ヒントを指定します。TABLOCK ヒントを使用すると、削除操作では行ロックまたはページ ロックではなく、テーブルの共有ロックを設定することになります。これにより、ページの割り当てを解除できます。TABLOCK ヒントの詳細については、「テーブル ヒント (Transact-SQL)」を参照してください。

  • すべての行をテーブルから削除する場合は、TRUNCATE TABLE を使用します。

  • 行を削除する前に、ヒープにクラスタ化インデックスを作成します。クラスタ化インデックスは、行を削除した後で削除できます。この方法は上記の方法よりも時間がかかり、より多くの一時リソースを使用します。

ロックの詳細については、「データベース エンジンのロック」を参照してください。

次の例では、WHERE 句を使用して削除する行数が制限されていないので、SalesPersonQuotaHistory テーブルからすべての行が削除されます。

USE AdventureWorks2008R2;
GO
DELETE FROM Sales.SalesPersonQuotaHistory;
GO

次の例では、ProductCostHistory テーブルから StandardCost 列の値が 1000.00 より大きいすべての行が削除されます。

USE AdventureWorks2008R2;
GO
DELETE FROM Production.ProductCostHistory
WHERE StandardCost > 1000.00;
GO

次の例は、結合または相関サブクエリに基づくベース テーブルからレコードを削除するために使用する Transact-SQL 拡張機能を示します。最初の DELETE ステートメントは ISO 互換のサブクエリ ソリューションを示し、2 つ目の DELETE ステートメントは Transact-SQL 拡張機能を示しています。両方のクエリにより、SalesPerson テーブルに格納されている今年に入ってからの売上高に基づいて SalesPersonQuotaHistory テーブルから行が削除されます。

-- SQL-2003 Standard subquery

USE AdventureWorks2008R2;
GO
DELETE FROM Sales.SalesPersonQuotaHistory 
WHERE BusinessEntityID IN 
    (SELECT BusinessEntityID 
     FROM Sales.SalesPerson 
     WHERE SalesYTD > 2500000.00);
GO
-- Transact-SQL extension
USE AdventureWorks2008R2;
GO
DELETE FROM Sales.SalesPersonQuotaHistory 
FROM Sales.SalesPersonQuotaHistory AS spqh
INNER JOIN Sales.SalesPerson AS sp
ON spqh.BusinessEntityID = sp.BusinessEntityID
WHERE sp.SalesYTD > 2500000.00;

GO