Этот случай - именно то, для чего подходят циклы (и для чего они предназначены).
Поскольку вы делаете вещи, которые выходят за рамки базы данных, вполне допустимо использовать для них циклы.
Базы данных предназначены для хранения данных и выполнения запросов к этим данным, которые возвращают их наиболее удобным способом.
Реляционные базы данных могут возвращать данные в виде наборов строк.
Курсоры (и их использующие циклы) предназначены для поддержания стабильного набора строк, чтобы можно было выполнять некоторые действия с каждым из его рядов.
Под «вещами» здесь я подразумеваю не просто трюки с базой данных, а реальные вещи, которые влияют на внешний мир, то, для чего предназначена база данных, будь то отображение таблицы на веб-странице, создание финансового отчета или отправка электронного письма.
Плохо использовать курсоры для чисто задач с базами данных (например, для преобразования одного набора строк в другой), но очень удобно использовать их для тех вещей, которые вы описали.
Методы на основе множеств предназначены для работы в одной транзакции.
Если ваш запрос set-base по какой-либо причине завершится неудачно, ваша база данных вернется в прежнее состояние, но вы не сможете "откатить" отправленное электронное письмо. Вы не сможете отслеживать свои сообщения в случае ошибки.