SQL Server удаляет строку за строкой и фиксирует несколько записей

#sql-server #transactions #sql-server-2016

Вопрос:

У меня есть сценарий, в котором мне нужно удалить каждую строку из таблицы, но зафиксировать несколько строк одновременно.

Например : у меня есть таблица #temp1 , в которой должно быть удалено 100 записей. Но после удаления каждых 10 записей мне нужно зафиксировать эти 10 удалений и так далее. Поэтому после того, как я должен совершить 10 раз, чтобы совершить все 100 удалений, но повторите 100 раз, чтобы удалить все 100 записей.

Я попробовал с циклом и транзакцией. Пример ниже :

 BEGIN TRANSACTION 
    While (@rowsdeleted <= @rowstodelete) 
    BEGIN 
      Delete records where condition is match 
      SET @deletedrows = @@rowcount  
    END
IF (deletedrows = 10)  
    BEGIN
      COMMIT TRANSACTION 
      SET deletedrows =0 
    END 
 

Эта логика фиксирует только одну строку на фиксацию. Это приведет к удалению 10 записей, и при совпадении условия фиксации будет зафиксирована только последняя удаленная запись, а остальные 9 записей не будут зафиксированы.

Есть ли у кого-нибудь какое-либо решение или логика для реализации этой проблемы ?

Комментарии:

1. Лучшим решением было бы прекратить выполнять удаления в цикле. Просто удалите строки, которые вы хотите удалить. Использование цикла для этого медленно и бессмысленно.

2. Если присмотреться к вашему коду повнимательнее, то это просто кошмар. Вы объявляете транзакцию за транзакцией внутри цикла.

3. @SeanLange Я использую цикл для удаления каждой строки, потому что после удаления этой строки мне также нужно использовать другую логику, что невозможно, если я не использовал цикл.

4. @SeanLange Я объявляю только одну транзакцию, но может быть еще несколько логик / проверок, которые мне, возможно, потребуется проверить.

5. Тогда почему вы пытаетесь выполнить эту странную логику фиксации каждые 10 строк? И нет, в вашем коде есть «НАЧАТЬ ТРАНЗАКЦИЮ» внутри вашего цикла. Вы сами создали себе здесь кошмар. Если у вас есть логика, которая настолько сложна для удаления одной строки, то вам, вероятно, следует создать хранимую процедуру для обработки всей этой логики. Затем вызовите свою процедуру в цикле. Или лучше, пересмотрите всю эту логику и сделайте так, чтобы вам не приходилось прыгать через обручи, чтобы удалять строки. Даже каскадное удаление было бы лучше.

Ответ №1:

 declare 
    @check_tran int, 
    @deletedrows int, 
    @total_deletedrows int, 
    @max_delete int 
begin
    set @max_delete = 100; 
    
    set @check_tran = 0
    set @total_deletedrows =0
    
    BEGIN TRANSACTION
    
    While (@total_deletedrows <= @max_delete) 
    BEGIN 
        
        Delete records where condition is match 

        SET @deletedrows = @@rowcount
        SET @check_tran = @check_tran   @deletedrows
        SET @total_deletedrows = @total_deletedrows   @deletedrows  
        print @deletedrows
    
        if (@check_tran >= 10) 
        begin 
            COMMIT TRANSACTION
            SET @check_tran = 0 
            BEGIN TRANSACTION
        end
    END

    -- when record count of table will be 105 records then 5 records are not be commited
    -- so if transaction count > 0 then commit transaction 
    if (@@TRANCOUNT>0) 
    begin
        COMMIT TRANSACTION
    end 
end