SQL Script - два оператора удаления - PullRequest
0 голосов
/ 11 июня 2018

Я нашел этот код в нашем репозитории, и мне нужно изменить оператор.Однако я немного колеблюсь, потому что мне интересно, почему у него два оператора удаления?Я попытался отладить его, удалить первое удаление, это не сработало.Я понимаю, что он будет запускать удаление на 100 строк.Есть ли вариант, что я могу иметь такое же поведение, но только один оператор DELETE?TIA!

USE [DBQ] 

SET ROWCOUNT 100
DELETE FROM dbo.setting WITH(ROWLOCK) WHERE CreateDate < DATEADD(day, -90, GETDATE())

WHILE @@rowcount > 0
BEGIN
 SET ROWCOUNT 100
 DELETE FROM  dbo.setting WITH(ROWLOCK) WHERE CreateDate < DATEADD(day, -90, GETDATE())
END

Ответы [ 3 ]

0 голосов
/ 11 июня 2018

Вы можете просто сделать поддельный выбор, чтобы получить @@ rowcount

select 1 
WHILE @@rowcount > 0
BEGIN
  DELETE top (100) 
  FROM  dbo.setting WITH(ROWLOCK) 
  WHERE CreateDate < DATEADD(day, -90, GETDATE())
END
0 голосов
/ 11 июня 2018

Добавьте переменную и измените ее значение внутри цикла.

declare @Start bit = 0
WHILE (@Start = 0 OR @@rowcount > 0)
BEGIN
  Set @Start = 1

  DELETE top (100) 
  FROM  dbo.setting WITH(ROWLOCK) 
  WHERE CreateDate < DATEADD(day, -90, GETDATE())
END
0 голосов
/ 11 июня 2018

Вы можете просто удалить rowcount:

DELETE FROM dbo.setting WITH(ROWLOCK)
    WHERE CreateDate < DATEADD(day, -90, GETDATE());

Обратите внимание на это из документации :

Использование SET ROWCOUNT не повлияет на DELETE,Операторы INSERT и UPDATE в будущих версиях SQL Server.Избегайте использования SET ROWCOUNT с операторами DELETE, INSERT и UPDATE в новых разработках и планируйте модифицировать приложения, которые в настоящее время используют его.Для аналогичного поведения используйте синтаксис TOP.Для получения дополнительной информации см. TOP (Transact-SQL).

Причина, по которой код будет написан таким образом, заключается в пакетной обработке delete s - удаление большого количества записей может занять много времени.

Если вы хотите сохранить пакетные удаления, сделайте что-то вроде:

declare @num_deleted int;
set @num_deleted = 999;

WHILE (@num_deleted > 0)
BEGIN 
     DELETE todelete
     FROM (SELECT TOP (100) s.*
           FROM dbo.setting s WITH(ROWLOCK)
           WHERE CreateDate < DATEADD(day, -90, GETDATE())
          ) todelete;

     set @num_deleted = @@rowcount;
END;
...