I have a table named a
that has 26 rows:
Select * from a
Output is 26
Begin Tran
Truncate table a
Select * from a
Output is zero rows
Rollback Tran
Select * from a
Output is again 26 rows
Truncate is ddl command we cannot perform rollback operation then why we get same number of rows after rollback ?
Please confirm in detail.
Yes, a TRUNCATE
can be rolled back in a transaction in SQL Server. There are actually only a few things that can't be rolled back with a transaction in SQL Server. For example, you can even roll back other DDL statements (such as the DROP
and CREATE
below):
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;
Despite "intellisense" probably telling you that dbo.Table2
doesn't exist in the lower batches, it does, as that transaction was rolled back. (Intellisense will also think that dbo.Table3
still exists, which it will not.)
Unlike the myth that people seem to believe, TRUNCATE
is logged. Unlike DELETE
, however, TRUNCATE
deletes the pages the data is stored on, not the individual rows. A log of what pages are deleted is still written, so a TRUNCATE
can still be rolled back, as the deletion of those pages is simply not committed.