truncate 后,我们不能回滚 SQL 中的数据?

After truncate , we can not rollback data in SQL?

我有一个名为 a 的 table,它有 26 行:

Select * from a

输出为 26

Begin Tran
Truncate table a
Select * from a

输出为零行

Rollback Tran
Select * from a

输出又是 26 行

Truncate 是 ddl 命令,我们不能执行回滚操作,那为什么我们在回滚后得到相同数量的行?

请详细确认

我认为误解是,在 Oracle 中 TRUNCATE 不能回滚。

在 SQL-Server Truncate 中仅删除整个 table-行,效率更高

是的,TRUNCATE 可以在 SQL 服务器的事务中回滚。在 SQL 服务器中,实际上只有少数事情无法通过事务回滚。例如,您甚至可以回滚其他 DDL 语句(例如下面的 DROPCREATE):

USE Sandbox;
GO

CREATE TABLE dbo.Table1 (I int);
CREATE TABLE dbo.Table2 (I int);
GO
WITH N AS (
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N))
INSERT INTO dbo.Table1
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
FROM N N1, N N2, N N3, N N4;

WITH N AS (
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N))
INSERT INTO dbo.Table2
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
FROM N N1, N N2, N N3, N N4;
GO

BEGIN TRANSACTION SampleTran;

TRUNCATE TABLE dbo.Table1;

CREATE TABLE dbo.Table3 (I int);

INSERT INTO dbo.Table3
SELECT I
FROM dbo.Table2;

DROP TABLE dbo.Table2;

ROLLBACK TRANSACTION SampleTran;
GO

--Contains 10,000 rows
SELECT *
FROM dbo.Table1;
GO
--Still exists
SELECT *
FROM dbo.Table2;
GO
--Doesn't exist
SELECT *
FROM dbo.Table3;
GO

--Clean up    
DROP TABLE dbo.Table1;
DROP TABLE dbo.Table2;

尽管 "intellisense" 可能告诉您 dbo.Table2 不存在于较低的批次中,但它确实存在,因为该事务已回滚。 (智能感知也会认为 dbo.Table3 仍然存在,但它不会。)

与人们似乎相信的神话不同,TRUNCATE 已记录。但是,与 DELETE 不同的是,TRUNCATE 会删除存储数据的 ,而不是单独的行。仍然会写入删除哪些页面的日志,因此 TRUNCATE 仍然可以回滚,因为这些页面的删除根本没有提交。

Truncate 不会删除实际数据,它只是取消分配页面。取消分配已记录,只需重新分配原始页面即可使事务回滚 - 数据完好无损:-)