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 中这两个循环删除查询有啥区别的主要内容,如果未能解决你的问题,请参考以下文章