【问题标题】:SQL Server : how to interrupt a SQL query halfway?SQL Server:如何中途中断 SQL 查询?
【发布时间】:2018-10-16 04:24:48
【问题描述】:

我正在尝试将几十万条记录插入到我的 SQL Server 表中。我想模拟数据库恢复,为此,我需要在插入过程中“中断”执行。我正在使用事务开始并逐批提交插入。假设我提交了 20k 条记录,并想为另外 20k 条记录开始事务,我想在第二批插入期间中断事务。

我知道终止执行,但它只是停止执行并且仍将插入记录。它不会以任何方式崩溃。我需要确保当我中断事务时,它最终不会被提交到数据库。

我有什么办法吗?

感谢任何建议。

【问题讨论】:

  • 您是否尝试终止该进程?应该做的伎俩。否则,找到红色的大按钮。
  • @TomC 红色的大按钮只是终止进程。如果它没有被提交,它真的会回滚整个过程吗?
  • 简单的解决方案是根据条件使用事务和回滚(包括TRY CATCH)。否则我们想知道你为什么要采取如此激烈的步骤。也许你也应该使用WAIT Delay
  • 您是如何插入记录的,单独或使用批处理方法(例如 INSERT TableA SELECT FROM Table B)。如果没有显式的 BEGIN TRANSACTION,则每个单独的 INSERT 都被视为隐式事务,并在执行语句时提交。因此,如果它崩溃,那么在此之前的任何 INSERTS 都是有效的并且永远不会回滚。正如@KumarHarsh 提到的,使用显式事务并在事务期间中止将使您处于恢复状态。
  • 我正在使用 Begin and Commit 事务逐批插入记录。我想先提交 20k 条记录,然后开始处理另外 20k 条记录,但在此过程中,我想中断它。

标签: sql sql-server


【解决方案1】:

我知道终止执行,但它只是停止 执行和记录仍将被插入。它不会崩溃 反正。我需要确保当我中断交易时,它 最终不会被提交到数据库。

这是错误的。 如果您中断INSERT,它将被回滚。 这是再现:

create table dbo.nums(n bigint not null);
go

insert into dbo.nums 
select row_number() over (order by getdate()) as n
from sys.columns c1 cross join sys.columns c2 cross join sys.columns c3;

如果你中断这段代码并执行

select * from dbo.nums;

你会发现它是空的。

所以,可以肯定的是,这个事务在被中断时永远不会被提交。

假设我提交了 2 万条记录并想开始交易 对于另外 20k 条记录,我想中断交易 在第二批插入期间。

您可以随意这样做,如果您想要更多时间来中断您的代码,只需添加waitfor delay

begin tran
    insert into dbo.nums 
    select row_number() over (order by getdate()) as n
    from sys.columns c1 cross join sys.columns c2 cross join sys.columns c3;

    waitfor delay '00:01:00';

...并确保它不会被提交。

【讨论】:

    【解决方案2】:

    如果您需要确保何时中断事务,它最终不会被提交到数据库。您需要使用:

      SET XACT_ABORT { ON | OFF }
    

    当 Transact-SQL 语句引发运行时错误时,这基本上会回滚当前事务

    查看链接了解更多信息

    https://docs.microsoft.com/en-us/sql/t-sql/statements/set-xact-abort-transact-sql?view=sql-server-2017

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-16
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      相关资源
      最近更新 更多