#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