使用 DELETE 删除行

DELETE 语句可删除表或视图中的一行或多行。

DELETE 语法的简化形式为:

DELETE table_or_view

FROM table_sources

WHERE search_condition

参数 table_or_view 指定要从中删除行的表或视图。table_or_view 中所有符合 WHERE 搜索条件的行都将被删除。如果没有指定 WHERE 子句,将删除 table_or_view 中的所有行。FROM 子句指定可由 WHERE 子句搜索条件中的谓词使用的其他表或视图及联接条件,以限定要从 table_or_view 中删除的行。不会从 FROM 子句指定的表中删除行,只从 table_or_view 指定的表中删除行。

任何已删除所有行的表仍会保留在数据库中。DELETE 语句只从表中删除行,要从数据库中删除表,可以使用 DROP TABLE 语句。

从堆中删除行

中删除行时,数据库引擎可以使用行锁定或页锁定进行操作。结果,删除操作导致的空页将继续分配给堆。未释放空页时,数据库中的其他对象将无法重用关联的空间。

若要删除堆中的行并释放页,请使用下列方法之一。

  • 在 DELETE 语句中指定 TABLOCK 提示。使用 TABLOCK 提示会导致删除操作获取表的共享锁,而不是行锁或页锁。这将允许释放页。有关 TABLOCK 提示的详细信息,请参阅表提示 (Transact-SQL)

  • 如果要从表中删除所有行,请使用 TRUNCATE TABLE。

  • 删除行之前,请对堆创建聚集索引。删除行之后,可以删除聚集索引。与先前的方法相比,此方法非常耗时,并且使用更多的临时资源。

有关锁定的详细信息,请参阅数据库引擎中的锁定

示例

下面的示例从 SalesPersonQuotaHistory 表中删除所有行,因为该例未使用 WHERE 子句限制删除的行数。

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 兼容的子查询解决方案,第二条 DELETE 语句显示 Transact-SQL 扩展插件。两个查询都将从 SalesPersonQuotaHistory 表中删除行,该表基于 SalesPerson 表中所存储的本年度迄今为止的销售业绩。

-- 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