DELETE和TRUNCATE语句之间的区别是求职面试中最常见的问题之一。这两条语句都可以从表中删除数据。然而,也有不同之处。
本文将重点讨论这些差异,并通过实例加以说明。
TRUNCATE |
DELETE |
从表中删除所有记录。我们不能使用WHERE删除特定的记录 |
删除所有记录,并可以使用WHERE删除特定记录。 |
不触发DELETE触发器。 |
触发DELETE触发器 |
重置标识列 |
不重置标识列 |
由于日志很少,所以速度更快。 |
由于执行了表扫描,以计算要删除的行数,并逐个删除行,所以会更慢。更改被记录在事务日志中。 |
使用行级锁 |
使用表级锁 |
需要ALTER TABLE权限 |
需要表的DELETE 权限 |
出于演示的目的,我创建了一个名为studentDB的表。除此之外,又创建了两个表,tblSchool和tblStudent,并在这两个表中插入了一些记录。
下面的语句创建了tblStudent表:
CREATE TABLE [dbo].[tblStudent]( [ID] [int] IDENTITY(1,1) NOT NULL, [student_name] [varchar](250) NOT NULL, [student_code] [varchar](5) NOT NULL, [student_grade] [char](2) NOT NULL, [SchoolID] [int] NOT NULL, CONSTRAINT [PK_tblStudent] PRIMARY KEY CLUSTERED ( [ID] ASC)) GO ALTER TABLE [dbo].[tblStudent] WITH CHECK ADD CONSTRAINT [FK_tblStudent_tblSchool] FOREIGN KEY([SchoolID]) REFERENCES [dbo].[tblSchool] ([School_ID]) GO ALTER TABLE [dbo].[tblStudent] CHECK CONSTRAINT [FK_tblStudent_tblSchool] GO
下面的语句创建了tblSchool表:
CREATE TABLE [dbo].[tblSchool]( [School_ID] [int] IDENTITY(1,1) NOT NULL, [School_Name] [varchar](500) NULL, [City] [varchar](50) NULL, CONSTRAINT [PK_tblSchool] PRIMARY KEY CLUSTERED ([School_ID] ASC)) ON [PRIMARY] GO
将数据插入到tblStudent表中:
insert into [dbo].[tblStudent] ([student_name],[student_code],[student_grade],[SchoolID]) values ('Nisarg Upadhyay','ST001','A',1), ('Nirali Upadhyay','ST002','B',1), ('Dixit Upadhyay','ST003','A',1), ('Bharti Upadhyay','ST004','C',2), ('Nimesh Patel','ST005','C',2), ('Raghav Dave','ST006','A',1) Go
将数据插入到tblSchool表中:
insert into [dbo].[tblSchool] ([school_name], [city]) values ('Nalanda School','Mehsana'), ('Sarvajanik School','Mehsana')
现在,我们来看看两者的不同之处。
1. 删除数据
DELETE命令的作用是从表中删除特定的/所有记录。TRUNCATE语句删除所有数据。
-
DELETE
要使用DELETE删除特定记录,可以在查询中使用WHERE子句。假设我们想从tblstudent表中删除一些学生,该学生的代码是ST002。在DELETE语句中添加如下条件:
Delete from tblstudent where student_code='ST002'
执行后,将只删除表中的一条记录。一旦记录被删除,运行select查询查看数据:
-
TRUNCATE
在truncate中,添加WHERE子句是不可能的。下面的查询删除了tblStudent表中的所有记录:
Truncate table tblStudent
2. 触发器
当我们运行DELETE语句时,SQL会调用DELETE触发器。
我已经在tblStudent上创建了一个名为trgdeleteStudent的触发器。当对tblstudent表执行DELETE语句时,触发器将在tblDeletedStudent表中插入一条记录。
创建tbldeletedStudent的T-SQL代码如下:
CREATE TABLE [dbo].[tblDelatedStudents] ( [ID] [int] IDENTITY(1,1) NOT NULL, [Student_Code] [varchar](10) NULL, CONSTRAINT [PK_tblDelatedStudents] PRIMARY KEY CLUSTERED ([ID] ASC) )
下面的代码创建了触发器:
create TRIGGER trgdeleteStudent on [tblStudent]
FOR DELETE
AS
INSERT INTO [dbo].[tblDelatedStudents](student_code)
SELECT student_code
FROM DELETED;
GO
运行以下查询删除学生ST0001的记录:
执行以下查询命令进行验证:
正如上面的截图中看到的,一条记录被添加到tblDelatedStudents表中。
现在,让我们运行TRUNCATE TABLE语句来删除tblstudent表中的数据:
Truncate table [dbo].[tblDelatedStudents]
通过查询tblDeletedStudent来验证数据:
如你所见,tblDeletedStudent表中没有插入记录。因此,trgdeletestudent触发器没有被触发。
3. 重置标识列
当执行DELETE语句时,标识列不会重置为初始值。对于TRUNCATE 语句,标识列将重置。
-
DELETE
执行DELETE语句删除tblStudent表中的数据:
然后,执行以下insert语句,向表tblStudent添加记录:
执行如下查询命令查看tblStudent的数据:
这里显示初始标识列值加1。
-
TRUNCATE
执行以下TRUNCATE语句删除tblStudent表中的数据:
删除数据后,在表中插入记录:
执行如下查询命令查看tblStudent的数据:
综上所述,标识列被重置了。
4. 权限
要使用DELETE语句删除数据,必须对表具有DELETE权限。要使用TRUNCATE TABLE语句删除数据,我们需要ALTER TABLE权限。
-
DELETE
我已经创建了一个名为testuser1的用户,并在tblStudent表上分配了删除权限。
我们删除student_code=ST001的学生记录:
use StudentDB go delete from tblstudent where student_code='ST001'
接着查看tblStudent的数据:
它确实从表中删除了记录。
-
TRUNCATE
现在,运行TRUNCATE删除数据:
查询返回如下错误:
Msg 1088, Level 16, State 7, Line 3
Cannot find the object "tblstudent" because it does not exist or you do not have permissions
为了纠正这个问题,我们必须分配ALTER TABLE权限。执行以下查询,授予tblStudent表访问权限:
重新执行truncate:
表中的数据被删除。
本文解释了DELETE语句和TRUNCATE 之间的区别。我们指出了常见的区别,并通过示例进行了说明。
原文链接:https://codingsight.com/difference-between-delete-and-truncate-table-in-sql-server/