在 SQL Server 中使用 DELETE 语句删除表中的数据后,表使用的空间未完全释放


Bug #:219514(SQL Server 8.0)

症状


在 Microsoft SQL Server 中使用 DELETE 语句删除表中的数据后,您可能会注意到表使用的空间未完全释放。 当您尝试在数据库中插入数据时,可能会收到以下错误消息:
无法为数据库 "DatabaseName" 中的对象 "TableName" 分配空间,因为 "PRIMARY" 文件组已满。
注意TableName表示表的名称。 DatabaseName 表示包含表的数据库的名称。

原因


出现此问题的原因是 SQL Server 仅释放当满足下列条件时堆表使用的所有页面:
  • 出现此表的删除。
  • 正在保留表级锁。
注意 堆表是与聚集索引没有关联的任何表。如果未释放页面,数据库中的其他对象将无法重用页面。 但是,当你在 SQL Server 2005 数据库中启用基于行版本控制的隔离级别时,即使正在持有表级锁,也无法释放页面。 有关基于行版本控制的隔离级别的详细信息,请参阅 SQL Server 2005 联机丛书中的 "使用基于行的基于行版本控制的隔离级别" 主题。

解决方法


若要解决此问题,请使用以下方法之一:
  • 如果未启用基于行版本控制的隔离级别,则在 DELETE 语句中包含一个 TABLOCK 提示。 例如,使用类似于以下内容的语句:
    DELETE FROM <TableName> WITH (TABLOCK)
    注意<TableName>表示表的名称。
  • 如果要删除表中的所有记录,请使用 "截断表" 语句。 例如,使用类似于以下内容的语句:
    TRUNCATE TABLE <TableName>
  • 在表的某一列上创建聚集索引。 有关如何在表上创建聚集索引的详细信息,请参阅 SQL Server 联机丛书中的 "创建聚集索引" 主题。

状态


Microsoft 已确认这是在“适用范围”部分中列出的 Microsoft 产品存在的问题。