【问题标题】:TRUNCATE in SQL Server rolls back on failure of last TRUNCATESQL Server 中的 TRUNCATE 在上次 TRUNCATE 失败时回滚
【发布时间】:2017-11-15 11:59:25
【问题描述】:

我正在启动一个事务并执行多个截断表语句,但如果最后一个失败,那么它会回滚所有截断。我试图在 SQL Server 命令提示符下描述相同的行为。

我正在尝试在 SQL Server 2012 中执行以下 SQL 语句:

create table pkt1(id integer)
GO

create table pkt2(id integer)
GO

insert into pkt1 values(10)
insert into pkt1 values(20)

insert into pkt2 values(10)
insert into pkt2 values(20)

select * from pkt1

输出:

id
------
10
20


select * from pkt2

结果:

id
------
10
20


begin transaction
   truncate table pkt1;
   truncate table pkt2;
   truncate table pkt3;
   commit;

错误:

消息 4701,级别 16,状态 1,服务器 PNI6W11198,第 4 行
找不到对象“pkt3”,因为它不存在或您没有权限。

select * from pkt2

输出:

id
------
10
20

select * from pkt1

输出:

id
-----
10
20

TRUNCATE 应该是 Transact SQL 并且应该为 pkt1 和 pkt2 提交更早的截断。但它确实为所有人回滚。

这是预期的行为吗?

【问题讨论】:

  • 如果截断包含在事务范围内且会话未关闭,则可以回滚。
  • 我相信这是因为错误发生在提交之前。您已经启动了一个事务块,这意味着在调用 commit 之前不会提交任何内容。见stackoverflow.com/questions/1522931/…
  • YES 这是预期的行为 - 这就是 transcation 的工作方式 - 并且应该可以工作。这里没有错(除了您的期望)
  • 我认为 TRUNCATE 是一个 Transact SQL,它的行为就像一个 DDL,并且会在每次 sql 执行后自动提交

标签: sql-server


【解决方案1】:

pkt3 不存在,因此脚本失败。

您的交易包含所有三个 truncate 语句:一个失败 - 它们都失败了

【讨论】:

  • 事务甚至从未开始。
猜你喜欢
  • 2022-08-24
  • 1970-01-01
  • 1970-01-01
  • 2018-07-22
  • 1970-01-01
  • 2020-01-24
  • 2011-12-11
  • 1970-01-01
  • 2011-11-06
相关资源
最近更新 更多