Ce cas est exactement ce pour quoi les boucles sont bonnes (et conçues).
Puisque vous faites des choses qui ne relèvent pas du champ d'application de la base de données, il est parfaitement légitime d'utiliser des boucles pour ces choses.
Les bases de données sont conçues pour stocker des données et effectuer des requêtes sur ces données afin de les restituer de la manière la plus pratique possible.
Les bases de données relationnelles peuvent renvoyer des données sous la forme de rowsets.
Les curseurs (et les boucles qui les utilisent) sont conçus pour conserver un jeu de lignes stable afin de pouvoir effectuer certaines opérations sur chacune de ses lignes.
Par "choses", j'entends ici non pas de purs trucs de base de données, mais des choses réelles qui affectent le monde extérieur, les choses pour lesquelles la base de données est conçue, qu'il s'agisse d'afficher un tableau sur une page web, de générer un rapport financier ou d'envoyer un courriel.
Il n'est pas bon d'utiliser les curseurs pour des tâches purement liées aux bases de données (comme la transformation d'un rowset en un autre), mais il est parfaitement possible de les utiliser pour des choses comme celle que vous avez décrite.
Les méthodes basées sur les ensembles sont conçues pour fonctionner dans le cadre d'une seule transaction.
Si votre requête de base échoue pour une raison quelconque, votre base de données reviendra à l'état antérieur, mais vous ne pouvez pas "annuler" un courriel envoyé. Vous ne serez pas en mesure de garder la trace de vos messages en cas d'erreur.