SQL Server 中这两个循环删除查询有啥区别

Posted

技术标签:

【中文标题】SQL Server 中这两个循环删除查询有啥区别【英文标题】:What is the difference between these 2 Looping Delete queries in SQL ServerSQL Server 中这两个循环删除查询有什么区别 【发布时间】:2020-02-02 00:08:31 【问题描述】:

我想找出在 while 循环中执行删除查询之间的区别,一个带有开始事务和一个没有。我试图从 2.5 亿行中删除 2 亿行,并在后台继续运行类似的东西。我无法截断,因为表中有外键。

这是针对 SQL Server 2012 的。我尝试了没有单词 begin transaction 和 commit transaction 的那个,它工作正常,但是一旦我将单词 begin transaction 和 commit 放入 while 循环中,表就会锁定,然后开始回滚一旦我停止在 SSMS 上执行。不使用开始交易这个词会更好吗?有什么区别。

SET NOCOUNT ON

DECLARE @Deleted_Rows INT;

SET @Deleted_Rows = 1;

WHILE @Deleted_Rows > 0

BEGIN

DELETE  TOP (4800) FROM s FROM mytable s
INNER JOIN Controltable f on s.fileid = f.fileid
where f.FileDate < GETDATE()-7

IF @@ROWCOUNT < @Deleted_Rows BREAK

    --WAITFOR DELAY '00:00:00:01';

END

SET NOCOUNT ON

DECLARE @Deleted_Rows INT;

SET @Deleted_Rows = 1;

WHILE @Deleted_Rows > 0

BEGIN
BEGIN TRANSACTION

DELETE  TOP (4800) FROM s FROM mytable s
INNER JOIN Controltable f on s.fileid = f.fileid
where f.FileDate < GETDATE()-7

IF @@ROWCOUNT < @Deleted_Rows BREAK

    --WAITFOR DELAY '00:00:00:01';
COMMIT TRANSACTION
END

我认为使用 begin 事务更安全,因为它在 while 循环内,它会每 4800 行提交一次,每当我停止执行时,它只会像 100 行或其他东西一样回滚,而是回滚所有百万行行。当我不使用提交事务和开始事务时,它工作正常并且不会回滚。只要我在 SSMS 中点击停止执行,就删除 4800 行并停止。这里发生了什么事?我错过了分号吗?查询错了吗?有没有更好的办法?

【问题讨论】:

SQL Server 支持隐式事务,这意味着每条语句在执行时都会被提交。 所以如果我不使用隐式事务,比如***查询,它不会被提交?那么当我停止执行时,更改是永久的怎么办?行被删除。 【参考方案1】:

您的提交事务在 BREAK 之后。因此,在最后一次运行时,您的 while 循环将中断,最后一个 BEGIN TRANSACTION 将没有相应的 COMMIT。

因此,您的脚本看起来好像总是会留下未处理的事务。对于最后一个被破坏的循环,您将需要在 while 循环之后进行单独的 COMMIT。

【讨论】:

啊,明白了!谢谢一堆。我需要在你说的休息前加上“承诺”

以上是关于SQL Server 中这两个循环删除查询有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

C ++中这两种强制转换方法有啥区别? [复制]

sql server 2005 一个索引多个字段,字段的排列顺序对搜索有啥影响??

SQL 中的 UNION 和UNION ALL 有啥区别?

SQL 中的 UNION 和UNION ALL 有啥区别?

下面有两个sql查询有啥区别

SQL嵌套子查询和相关子查询的执行过程有啥区别