この記事は、DELETE ステートメントを使用してテーブルからすべてのデータを削除した後に、テーブルで使用される問題を回避するのに役立ちます。
元の製品バージョン: SQL Server
元の KB 番号: 913399
現象
Microsoft SQL Server で DELETE ステートメントを使用してテーブルからデータを削除すると、テーブルで使用される領域が完全には解放されないことがあります。 その後、データベースにデータを挿入しようとすると、次のエラー メッセージが表示されることがあります。
データベース 'DatabaseName' のオブジェクト 'TableName' に領域を割り当てませんでした。'PRIMARY' ファイル グループがいっぱいです。
Note
TableName はテーブルの名前を表します。 DatabaseName は、テーブルを含むデータベースの名前を表します。
原因
この問題は、次の条件に該当する場合に、SQL Server によってヒープ テーブルで使用されるすべてのページのみが解放されるために発生します。
- このテーブルは削除されます。
- テーブル レベルのロックが保持されています。
Note
ヒープ テーブルは、クラスター化インデックスに関連付けられていない任意のテーブルです。
ページの割り当てが解除されていない場合、データベース内の他のオブジェクトはページを再利用できません。
ただし、SQL Server データベースで行 versioning-based
分離レベルを有効にすると、テーブル レベルのロックが保持されている場合でもページを解放できません。 行versioning-based
分離レベルの詳細については、「SQL Server データベース エンジンのIsolation レベル」を参照してください。
回避策
この問題を回避するには、次のいずれかの方法を使用します。
行のバージョン管理ベースの分離レベルが有効になっていない場合は、DELETE ステートメントに TABLOCK ヒントを含めます。 たとえば、次のようなステートメントを使用します。
DELETE FROM <TableName> WITH (TABLOCK)
Note
<TableName> は、テーブルの名前を表します。
テーブル内のすべてのレコードを削除する場合は、TRUNCATE TABLE ステートメントを使用します。 たとえば、次のようなステートメントを使用します。
TRUNCATE TABLE <TableName>
テーブルの列にクラスター化インデックスを作成します。 テーブルにクラスター化インデックスを作成する方法の詳細については、「 クラスター化インデックスの作成」を参照してください。