SQL Server DELETE 命令是一个 DML(数据操作语言)语句,用于从数据库表或视图中删除一个或多个现有行。DELETE 语句对于维护数据库中表的数据完整性和准确性至关重要。
与删除表中所有记录的 TRUNCATE 命令不同,SQL DELETE 语句对行删除有更多的控制。主要优点是 DELETE 允许您使用 WHERE 子句指定条件。因此,您可以根据单个条件或多个条件删除记录。否则,可以删除多条记录或整个数据集。
通常,在一个组织中,一段时间后,我们存储在数据库中的数据量会增长,这些记录可能与当前情况无关或已过时。要删除这些过时的记录或清理日志,您可以使用 SQL Server DELETE 语句。
与从数据库中删除整个表的 DROP 命令不同,DELETE 语句根据条件(如果有)删除行,并保留表结构、约束等。
提示:一旦执行 SQL DELETE 命令,除非使用事务,否则无法逆转该过程并检索数据。
SQL DELETE 语句语法
SQL DELETE 命令的基本语法,以及用于对 SELECT 语句应用条件的 WHERE 子句是:
DELETE FROM [Table_Name] WHERE Condition
如果您查看语法,我们没有在 SQL DELETE 语句中提到列列表。因为删除操作是按行执行的,所以我们需要表名。让我为您分解语法。
- Table_Name:要执行删除操作的表的名称。
- WHERE Condition:这是一个可选参数,提供删除的过滤器或条件。如果条件为 TRUE,则此语句将从给定表中删除记录。
在 WHERE 子句的帮助下,您可以根据条件删除单个单词或多条记录。但是,如果您完全省略 WHERE 子句,SQL DELETE 语句将删除表中的所有记录。
除了上述简单语法之外,还有一个包含 TOP 子句的复杂语法。
DELETE [TOP(Value) [PERCENT]]
FROM Table_Name
[WHERE condition]
TOP (Value) | PERCENT:这里,TOP 子句是一个可选参数,如果您使用它,SQL DELETE 语句将根据给定的整数或百分比值从表中删除前面的几条记录。
让我向您展示一些您在实际中可能遇到的最常见示例。它包括删除表中的所有记录、单行、多行、单个条件和多个条件等。在本文中,我们将使用下表执行不同类型的 DELETE 操作。

要避免的常见错误
在我们深入研究 SQL DELETE 语句示例之前,让我向您展示实际中要避免的最常见错误。
- 在编写 DELETE 查询时,忘记 WHERE 子句并执行是一个常见且代价高昂的错误。
- 在清空表时使用 DELETE 命令而不是 TRUNCATE 语句。
- 在删除记录之前忘记备份表。
- 在对父子表执行 DELETE 操作时理解参照完整性。
提示:您可以使用逻辑运算符来组合 WHERE 子句中的多个条件。
SQL 删除单行
SQL Server DELETE 语句允许您从给定表中删除单行或记录。想象一下有一个 Employee 表,您想删除一个不在组织中工作的员工。在这种情况下,您可以使用 WHERE 条件根据员工 ID 过滤表。然后,删除该特定行。
要执行这些操作,您必须使用比较运算符,如 =、<=、>= 等来检查条件。为了演示这一点,我们将从 employee 表中删除 EmpID = 2。
DELETE FROM [Employee]
WHERE [EmpID] = 2
它将删除 ID 值为 2 的员工记录,这是一条记录。假设没有行满足条件(没有 ID 为 2 的员工),则上述语句不执行任何操作。
根据多个条件删除单条记录
上面的 SQL 示例是一个简单的示例,因为我们在 WHERE 子句中使用单个条件从表中删除单行。但是,在某些情况下,我们必须检查多个条件以确保我们删除了完全匹配的行。
例如,在上表中,我们有三名员工的名字都叫 John,更糟糕的是,其中两条记录的教育和职业甚至都相同。在这种情况下,我们使用 逻辑 AND 操作来匹配名字和姓氏,以删除特定记录。
DELETE FROM [Employee]
WHERE [FirstName] = 'John' AND [LastName] = 'Ruiz'
注意:如果您不小心忘记了 WHERE 子句,那么您最终将删除源中的所有记录。
SQL 删除表中的多行
在某些情况下,需要删除表中的多条记录。例如,删除绩效不佳或旧的部门。另一种情况是删除整个城市或州的数据。假设以下查询删除了所有属于洛杉矶的客户。
DELETE FROM Customers WHERE City = 'Los Angeles'
让我给您一个快速示例来演示多列的删除。以下查询将删除表中教育资格为“部分高中”的所有记录。
DELETE FROM [Employee]
WHERE [Education] = 'Partial High School'
提示:使用 @@ROWCOUNT 显示语句删除的记录总数。

SQL 根据多个条件删除多行
与上述 SQL DELETE 语句或命令示例类似,我们可以使用多个条件创建更复杂的查询以获得精确的结果集。在此示例中,我们使用 WHERE 子句中的 AND 运算符在开始删除记录之前检查多个条件。第一个条件测试职业是否为“专业人士”,AND 运算符是连接词。下一个条件检查年收入是否小于 90000。如果两个条件都为 TRUE,则该员工记录将从表中删除。
DELETE FROM [Employee]
WHERE [Occupation] = 'Professional' AND [YearlyIncome] < 90000
使用 BETWEEN 运算符删除多行
如果将 SQL DELETE 语句与 BETWEEN 运算符和逻辑 AND 运算符一起使用,则可以删除范围内的行。例如,删除特定日期范围(从 A 到 B 日期)内的客户、订单或员工。
以下示例删除在“2006-01-27 AND ‘2007-01-28’”之间入职(他们的雇佣日期)的员工。
DELETE FROM [Employee]
WHERE [HireDate] BETWEEN '2006-01-27' AND '2007-01-28'
使用 SQL 中的 IN 运算符删除多行
上述示例对于删除一系列记录或与多个或单个条件匹配的行很有用。但是,在某些情况下,我们必须删除特定的一组单个记录。例如,删除不同的员工或学生 ID。
下面的 IN 查询删除了 ID 值为 5、10、12 和 15 的员工。
DELETE FROM [Employee] WHERE EmpID IN (5, 10, 12, 15)
SQL 删除表中的所有行
SQL Server 允许您删除表中的所有记录或行,而不会干扰表结构。当您想删除所有旧的或不需要的数据时,这非常有用。
如果您需要清空表,可以通过以下三种选项之一实现:首先,简单地省略 WHERE 子句。
DELETE FROM table_name
其次,使用 WHERE 子句,条件始终返回 TRUE(1 = 1)。
DELETE FROM table_name WHERE 1 = 1
第三,使用 *(星号)选择所有行。
DELETE * FROM table_name
尽管我们可以使用这三个选项中的任何一个来实现目标,但始终选择第一个 SQL DELETE 语句选项,它直接删除表中存在的所有记录。所以,让我使用相同的选项来清空上面提到的表。
DELETE FROM Employee
由于上述查询清空了现有表,让我从备份中插入这 15 条记录以执行后续操作。

SQL Server DELETE TOP 子句
SQL Server 允许您将 TOP 子句与 DELETE 语句一起使用,以根据数字或给定百分比删除前面几条记录。例如,如果您想从表中删除前 50 行或 10% 的记录,请使用此 TOP 子句。
在此示例中,我们从表中删除年收入小于或等于 5000 的第一条记录。对于此示例,我们使用带有 TOP 子句和 WHERE 语句的 DELETE 命令。
WHERE 子句将检查年收入小于或等于 5000 的记录,然后 TOP 子句将选择第一条记录。最后,DELETE 命令将删除该记录。
DELETE TOP (1) FROM [Employee]
WHERE [YearlyIncome] <= 50000
如果您的目标是删除前 3 条记录,无论条件如何,您可以省略 WHERE 子句。
DELETE TOP (3) FROM [Employee]
子查询中的 ORDER BY
请记住,DELETE TOP 子句按照记录在表中保存的顺序选择和删除记录。如果您对要删除的记录有特定要求,请在语句中使用 SQL ORDER BY 子句,根据列以 ASC 或 DESC 顺序对它们进行排序。为了演示这一点,您必须使用子查询。
以下查询从表中删除前五名员工记录,按他们的年收入(最低收入)排序。
DELETE FROM [Employee] WHERE [EmpID] IN (
SELECT TOP 5 EmpID FROM Employee
ORDER BY YearlyIncome ASC)
带 CTE
除了上述子查询选项外,您还可以使用公共表表达式 (CTE) 以特定方式获取排序结果。接下来,在 CTE 上执行 SQL DELETE 操作,而不是在表上执行。
以下查询创建一个 CTE,该 CTE 选择年收入大于 5000 的前五名员工,按收入降序排列。接下来,DELETE 语句使用 CTE 删除这些记录。
WITH Test
AS (
SELECT TOP 5 EmpID FROM Employee
WHERE [YearlyIncome] > 50000
ORDER BY YearlyIncome DESC )
DELETE FROM Test

DELETE 命令中的 SQL 事务
在执行数据操作(例如 DELETE 操作)时,您必须使用 TRANSACTION 概念。它有助于避免错误并将数据回滚到原始状态,这样您就不必从备份中恢复数据。
这意味着您以 BEGIN TRANSACTION、DELETE COMMAND、ROLLBACK(出现问题)开始查询,否则 COMMIT TRANSACTION。如果在 DELETE 命令之后使用 ROLLBACK TRANSACTION,您可以将表数据恢复到起始位置或任何保存点,而无需从备份中恢复数据。
BEGIN TRANSACTION
DELETE FROM Employee WHERE Occupation = 'Professional'
-- SELECT * FROM Employee
ROLLBACK TRANSACTION
-- SELECT * FROM Employee
请尝试取消注释上述查询中的 SELECT 语句,以实时查看 TRANSACTION 的魔力。
带 JOIN 查询的 SQL DELETE 命令
在某些情况下,我们需要根据在另一个表中测试的条件从一个表中删除记录。在这种情况下,我们使用 JOIN 概念来连接两个或更多表并执行删除。第一张图将显示 Department 表中的日期。
让我根据另一个表中的部门名称从 employee 表中删除记录。为此,我们使用 内连接 和 SQL DELETE 语句来连接两个表。以下查询删除所有部门名称为 Sr. Software Developer 的记录。请记住,部门名称来自 Department 表。
DELETE e
FROM [Employee] AS e
INNER JOIN Department AS d ON e.[DeptID] = d.id
WHERE d.DepartmentName = 'Sr. Software Developer'
如果您有 AdventureWorksDW 数据库,您可以使用以下查询删除男性客户的销售记录。尝试在 DimGeography 上进行实验,按国家、州、城市和邮政编码删除销售记录。
DELETE fact
FROM FactInternetSales fact
JOIN DimCustomer cus ON fact.CustomerKey = cus.CustomerKey
WHERE cus.Gender = 'M'
使用另一个表删除行
在实际中,为了维护公共数据,在某些情况下,我们必须将一个表(原始表)中的数据与源表进行比较。如果源表和目标表中有一些重复或公共记录,那么我们必须从这些表中删除它们。在这种情况下,我们可以连接两个表并在一个表上执行 SQL Server DELETE 操作。
以下查询将删除 Employee 表中所有 ID 与 Emp 表相同的匹配记录。
DELETE Employee
FROM Employee
JOIN Emp ON Employee.EmpID = Emp.EmpID
以下查询删除 Employee 表中所有与 Emp 不匹配的记录。
DELETE Employee
FROM Employee
JOIN Emp ON Employee.EmpID != Emp.EmpID
SQL DELETE 命令外键错误修复!
通常,数据库表的设计方式是它们使用主键和外键关系相互连接。在创建父子关系时,参照完整性在执行 SQL Server DELETE 操作中起着主要作用。
如果您观察默认的 Adventure Works 数据库,大多数外键都标记为“无操作参照完整性”。因此,当您尝试从主表中删除记录时,如果子表有依赖记录,则查询将抛出错误。避免孤立记录非常重要。例如,如果您尝试从 Department 表中删除记录,它将抛出错误,因为 Dept ID 在 Employee 表中有引用。
为了处理孤立记录,您可以编写一个 SQL DELETE 语句来删除主表中的记录以及 Employee 表中所有相关的员工。要实现相同目的,您有两个选项。
选项 1:CASCADE DELETE
如果您已经使用 CASCADE DELETE 参照完整性创建了外键,那么这是一种简单直接的技术。以下查询将删除部门名称为“经理”的部门以及所有 ID 值为 6(经理)的员工记录。
DELETE FROM Department
WHERE DepartmentName = ‘Manager’
选项 2:多个 DELETE 查询
如果您没有使用 CASCADE 创建外键,那么上述查询将抛出错误。为了解决这个问题,您必须运行两个单独的 SQL DELETE 语句查询来删除记录。第一个查询必须删除部门为项目经理的员工行,然后编写第二个查询以从 Department 表中删除项目经理记录。
BEGIN TRANSACTION
DELETE FROM Employee
WHERE DeptID IN (
SELECT id FROM Department WHERE DepartmentName = 'Project Manager');
DELETE FROM Department WHERE id = 5;
COMMIT TRANSACTION;
您还可以用 JOIN 替换 IN 运算符查询,并且可以获得相同的结果。
DELETE FROM Employee
JOIN Department ON Employee.DeptId = Department.id
WHERE DepartmentName = ' Project Manager';
DELETE FROM Department WHERE id = 5;

使用子查询的 SQL DELETE FROM
使用子查询编写 DELETE 语句对于根据内部查询获得的结果集从表中删除记录非常有用。在我们之前的 TOP 子句示例中,我们展示了一个子查询示例,您可以参考该示例以获得基本理解。
在这个从子查询结果集示例中,我们不知道部门 ID。但是我们想删除部门名称为 Module Lead 的员工。在这种情况下,我们使用 子查询 从部门名称为 Manager 的 Department 表中选择记录。接下来,我们使用 DELETE 命令和 WHERE 子句与 IN 运算符来删除子查询编写的多条记录。
DELETE FROM [Employee] WHERE [DeptID] IN
(
SELECT id FROM Department WHERE DepartmentName = 'Manager'
)
删除表中所有部门名称为 Manager 的记录。如果您知道 ID,可以尝试使用以下查询,但这不是正确的方法。
DELETE FROM [Employee] WHERE [DeptID] = 3
以下查询将删除表中所有年收入低于表平均值的员工。内部子查询查找并返回整个表的平均收入。主 DELETE 命令将删除年收入低于平均值的员工。
DELETE FROM Employee
WHERE YearlyIncome <
( SELECT AVG(YearlyIncome) FROM Employee)
SQL Server DELETE 行(如果存在)
WHERE 子句无法检查单个表中的数据。在某些情况下,我们必须根据第二个表的条件删除记录。例如,在从表中删除记录时,始终最好检查记录是否存在。
以下查询使用 EXISTS 运算符检查 Employee 表中的记录与 Department 表中的记录。如果它们存在且其部门名称为 CEO,则 DELETE 语句将删除该记录。
剩余数据 视图 为
DELETE sd FROM [Employee] as sd
WHERE EXISTS (
SELECT * FROM Department
WHERE sd.DeptID = Department.id
AND DepartmentName = 'CEO'
)
删除重复记录
假设客户表中有一些重复记录,我们的任务是删除这些记录。在 SQL Server 中,我们可以使用子查询或 CTE 查找重复项,并使用 DELETE 语句删除这些记录。
一般来说,最后插入的记录可能是正确或需要的记录。因此,以下查询将保留最高的 ID 值(假设是最新值)并删除重复项。如果需要,您可以将 MAX 替换为 MIN 函数。
DELETE FROM customers
WHERE CustomerID NOT IN (
SELECT MAX(CustomerID) FROM customers
GROUP BY FirstName, LastName, DOB
)
另一个选项是使用 CTE 和 ROW_NUMBER() 排名函数。在以下查询中,ROW_NUMBER() 函数 为分区组中的每一行分配一个唯一的编号。在这里,它将为每个客户分配编号。接下来,我们使用 DELETE 语句删除行号大于 1 的记录。
WITH CTE AS (
SELECT *, ROW_NUMBER() OVER (
PARTITION BY FirstName, LastName, DOB ORDER BY CustomerID) AS rank
FROM customer)
DELETE FROM CTE WHERE rank > 1
SQL Server DELETE 和 IS NULL 语句示例
表中的 NULL 值表示缺失数据。在某些情况下,我们必须摆脱这些 NULL 值。在这种情况下,我们使用 DELETE 语句以及 IS NULL 运算符。
如您所知,AdventureWorksDW DimProduct 表中有许多产品的 Product Description 为空或 NULL。因此,让我编写一个查询来删除所有 Description 为 NULL 的产品。
DELETE FROM DimProduct
WHERE ProductDescription IS NULL
在 SQL DELETE 语句中使用 OUTPUT 子句
OUTPUT 子句保存并显示 DELETE 命令删除的记录总数。例如,以下查询删除销售额小于 1000 的员工。但是,OUTPUT 子句将显示被删除的总记录作为结果集。在这里,如果需要少量列,可以将 * 替换为所需的列名。
DELETE Employee
OUTPUT DELETED.*
WHERE Sales < 1000;
上述查询是使用 OUTPUT 子句显示已删除结果集的简单版本。但是,如果您使用 表变量,您可以存储 OUTPUT 子句返回的结果集并执行进一步的操作。以下查询将创建一个表变量并使用 OUTPUT 子句保存 DELETE 语句删除的行。接下来,SELECT 语句将从变量中显示这些记录。
DECLARE @Variable TABLE (
[EmpID] [int] NOT NULL,
[FirstName] [nvarchar](255) NULL,
[LastName] [nvarchar](255) NULL,
[Education] [nvarchar](255) NULL,
[Occupation] [nvarchar](255) NULL,
[YearlyIncome] [float] NULL,
[Sales] [float] NULL,
DepartmentName VARCHAR(50) NULL);
DELETE Employee
OUTPUT DELETED.EmpID, DELETED.FirstName, DELETED.LastName,
DELETED.Education,DELETED.Occupation,DELETED.YearlyIncome,
DELETED.Sales, d.DepartmentName
INTO @Variable
FROM Employee
JOIN Department as d
ON Emp.DeptID = d.id
WHERE d.DepartmentName = 'Software Developer';
SELECT * FROM @Variable
使用 LIKE 运算符的 DELETE 命令
如果在 WHERE 子句中使用 SQL LIKE 运算符,我们可以对记录执行通配符搜索,并且 DELETE 命令将删除匹配的记录。例如,您可以使用 DELETE 和 LIKE 组合来删除属于城市名称以 C、N 等开头的客户。
以下查询将删除教育中包含“High”关键字或教育以“Degree”结尾的员工。我建议您尝试更多通配符以获得更好的知识。
DELETE FROM [Employee]
WHERE Education LIKE '%High%' OR Education LIKE '%Degree'
SQL 删除存储过程
让我们看看如何在 存储过程 中使用此语句。在这里,我们删除职业等于文员或年收入小于或等于 60000 的记录。
IF OBJECT_ID ( 'sp_DeleteEmpRecords', 'P' ) IS NOT NULL
DROP PROCEDURE sp_DeleteEmpRecords;
GO
CREATE PROCEDURE sp_DeleteEmpRecords
AS
BEGIN
SET NOCOUNT ON;
DELETE FROM [Employee]
WHERE Occupation = 'Clerical' OR
YearlyIncome <= 60000
END
GO
Messages
-------
Command(s) completed successfully.
让我使用 EXEC 命令来执行存储过程。
EXEC dbo.sp_DeleteEmpRecords
GO
Messages
-------
Command(s) completed successfully.
现在,让我们看看存储过程的执行是否清除了我们表中的行。
-- Select all records from a Table after executing the SP
SELECT * FROM [ProductSale]

使用 Management Studio 的 SQL Server Delete 语句
如果您可以访问 Management Studio 的 SQL Server,则有多个选项可以从数据库表中删除记录。
选项 A:使用编辑前 200 行
请右键单击表,然后从菜单中选择“编辑前 200 行”选项。接下来,使用 Ctrl 或 Command 键仔细选择所需的行。然后,右键单击它们以打开上下文菜单。选择“执行 SQL 命令”以进一步验证它们,或选择“删除”选项以永久从表中删除这些行。
提示:在 DELETE 命令之前使用 SELECT 语句,以检查您要从表中删除的记录是否是结果集中显示的记录。
选项 B:使用脚本表
除了上述两个选项之外,您还可以使用 IntelliSense 编写 DELETE 语句。它非常高级,您可以更好地控制查询。为此,右键单击表 -> 选择“将表脚本化为” -> “删除到” -> “新查询编辑器窗口”。它将为所选表生成语句,代码如下所示。
USE [Sample]
GO
DELETE FROM [dbo].[Employee]
WHERE <Search Conditions,,>
GO
首先,让我将表备份到原始位置。接下来,让我们添加下面所示的搜索条件。
DELETE FROM [dbo].[Employee] WHERE EmpID = 1
SQL DELETE 语句最佳实践
以下是编写有效 SQL DELETE 语句的一些最佳实践。
- 用户权限: DELETE 操作非常敏感,因此您必须限制未经授权的人员删除表。
- 数据备份:在实施 DELETE 操作之前,务必进行备份,以避免数据丢失。如果您正在处理大型数据集,数据丢失将是巨大且不可逆的。
- WHERE 子句: 在编写 DELETE 命令时,始终使用 WHERE 子句。如果您确定要删除整个数据集,则只可省略 WHERE 子句。
- 索引列: 确保在 WHERE 子句中使用索引列,以数倍提高查询性能。
- SELECT: 在实施 SQL DELETE 命令之前,使用 SELECT 语句查看数据。或使用 SELECT COUNT(*) 查看受影响的总行数。
- 事务: 始终将完整的 DELETE 语句包装在 BEGIN 和 END TRANSACTION 中是一个好习惯,以确保数据完整性。如果在执行过程中出现问题,您可以 ROLLBACK 到原始状态。
- 分批处理: 在处理大型数据集时,分小批(TOP 子句)执行删除操作,以提高查询性能并避免阻塞。
- 删除所有行: 使用 TRUNCATE 语句清空整个表是一个好习惯。因为它更快,并且不维护每条记录删除的事务日志。
- OUTPUT 子句: 使用 OUTPUT 子句显示 DELETE 语句删除的行。
- 外键错误: 当存在父子关系时,从表中删除记录将抛出错误。除非您使用 CASCADE DELETE 规则创建了外键。否则,首先从子表中删除记录,然后从父表中删除。
- 禁用触发器和约束:在使用大型数据集时,禁用外键约束。此外,相关的触发器也将提高性能。但是,您应该知道这些触发器存在的原因及其重要性。要禁用触发器:ALTER TABLE Employee DISABLE TRIGGER ALL。DELETE 操作完成后,编写上述 ALTER 语句并将 DISABLE 关键字替换为 ENABLE。
SQL DELETE 与 TRUNCATE 与 DROP
Microsoft SQL Server 提供三个命令:DELETE、TRUNCATE 和 DROP。由于它们的相似性,人们常常对它们的操作感到困惑,这里我们展示它们的区别。
- DELETE: 根据用户给定的条件,删除表中的单条或多条记录。
- TRUNCATE: 一次性删除表中的所有记录或行,并重置标识列。
- DROP: 从数据库中删除整个表。
下表将说明 SQL Server 中 DELETE、TRUNCATE 和 DROP 命令之间最常见的区别。
| 删除 | TRUNCATE | DROP |
|---|---|---|
| DELETE 是数据操作语言 (DML) 语句。 | TRUNCATE 是数据定义语言 (DDL) 语句。 | DROP 是 DDL 语句。 |
| 它根据条件删除一行或多行。 | 删除所有记录并保留表结构。 | 删除表、结构和约束。 |
| 使用 DELETE 命令删除单行或多行。 | 使用 TRUNCATE 删除表中的所有记录并保留表结构。 | 使用 DROP 命令删除表或数据库。 |
| 它允许 WHERE 子句过滤要删除的记录。 | 它不支持 WHERE 子句。 | 不支持 WHERE 子句。 |
| 它不重置标识列值。 | 它重置标识列值。 | 不适用。 |
| DELETE FROM orders WHERE OrderDate < '2020-01-01' | TRUNCATE TABLE orders | DROP TABLE orders |
| 它记录每次行删除,因此事务日志很高。 | 它只记录数据页,因此事务空间较少。 | 它记录整个表的删除。因此,它维护完整的日志。 |
| 性能比其他两个慢。 | 比 DELETE 快 | 三者中最快。 |
| 如果存在 CASCADE DELETE 参照完整性,则可以使用 SQL 外键引用删除记录。 | 您不能截断具有外键引用的表。 | 当其他表引用该表时,您无法删除该表。因此,首先删除依赖表或关系,然后应用操作。 |
| 它将触发表上的 DELETE 触发器。 | 它不会触发表上的任何触发器。 | 它不会触发表上的触发器。 |
| 它保持触发器和约束不变。 | 它不会删除触发器和约束。 | 它删除表上的约束和触发器 |