После truncate нельзя откатить данные в SQL?

У меня есть таблица с именем a, в которой 26 строк:

Select * from a

Выход 26

Begin Tran
Truncate table a
Select * from a

Вывод - ноль строк

Rollback Tran
Select * from a

Вывод снова 26 строк

Truncate - это команда ddl, мы не можем выполнить операцию отката, тогда почему мы получаем такое же количество строк после отката?

Пожалуйста, подтвердите подробно.


person Ankush    schedule 01.03.2020    source источник
comment
Где commit ?   -  person Yogesh Sharma    schedule 01.03.2020
comment
@yogesh: да, после отката фиксации, почему мы получаем такое же количество строк 26   -  person Ankush    schedule 01.03.2020
comment
@ankush нет никаких доказательств фиксации вашей транзакции.   -  person P.Salmon    schedule 01.03.2020
comment
@P.Salmon: да, я хочу подтвердить .... мы не можем выполнить откат   -  person Ankush    schedule 01.03.2020
comment
@Анкуш. . . Ваш третий запрос не должен отображать результат. Кстати, он должен быть на стадии эксплуатации. Поскольку вы не указали commit. Так что он пока в стадии эксплуатации.   -  person Yogesh Sharma    schedule 01.03.2020
comment
ой спасибо йогеш понял   -  person Ankush    schedule 01.03.2020


Ответы (3)


Да, TRUNCATE можно откатить в транзакции в SQL Server. На самом деле есть только несколько вещей, которые нельзя откатить с помощью транзакции в SQL Server. Например, вы даже можете откатить другие операторы DDL (например, DROP и CREATE ниже):

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 не существует в более низких пакетах, он существует, поскольку эта транзакция была отменена. (Intellisense также будет думать, что dbo.Table3 все еще существует, а это не так.)

В отличие от мифа, в который люди верят, TRUNCATE регистрируется. Однако, в отличие от DELETE, TRUNCATE удаляет страницы, на которых хранятся данные, а не отдельные строки. Журнал того, какие страницы были удалены, все еще записывается, поэтому TRUNCATE все еще можно откатить, так как удаление этих страниц просто не зафиксировано.

person Larnu    schedule 01.03.2020

Я думаю, что недоразумение заключается в том, что в Oracle TRUNCATE нельзя откатиться.

В SQL-Server Truncate просто удаляет целые строки таблицы с большей эффективностью.

person Turo    schedule 01.03.2020
comment
В SQL-Server Truncate просто удаляет целые строки таблицы с большей эффективностью это совершенно неверно. DELETE и TRUNCATE просто работают по-разному. Я бы не сказал, что TRUNCATE эффективнее, чем DELETE, потому что они на самом деле несопоставимы. TRUNCATE фактически удаляет страницы, на которых хранятся данные, а DELETEудаляет каждую строку. - person Larnu; 01.03.2020
comment
Из документации: TRUNCATE TABLE похож на оператор DELETE без предложения WHERE; однако TRUNCATE TABLE работает быстрее и использует меньше системных ресурсов и ресурсов журнала транзакций. Может быть, это немного просто, но довольно близко - person Turo; 01.03.2020

Truncate не удаляет фактические данные, он просто освобождает страницы. Отмена распределения регистрируется, позволяет откатить транзакцию, просто перераспределив исходные страницы - данные не повреждены :-)

person Matt Bowler    schedule 01.03.2020