Vous pouvez ajouter la valeur de l'identifiant à la fin du nom lorsqu'un enregistrement est supprimé. Ainsi, lorsque quelqu'un supprime l'identifiant 3, le nom devient Thingy3_3, puis lorsqu'il supprime l'identifiant 100, le nom devient Thingy3_100. Cela vous permettrait de créer un index composite unique sur le nom et les champs supprimés, mais vous devez ensuite filtrer la colonne du nom chaque fois que vous l'affichez et supprimer l'identifiant à la fin du nom.
Une meilleure solution serait peut-être de remplacer votre colonne supprimée par une colonne delete_at de type DATETIME. Vous pouvez alors maintenir un index unique sur le nom et supprimé à, avec un enregistrement non supprimé ayant une valeur nulle dans le champ delete_at. Cela empêcherait la création de plusieurs noms dans un état actif mais vous permettrait de supprimer le même nom plusieurs fois.
Vous devez évidemment faire un test lors de la restauration d'un enregistrement pour vous assurer qu'il n'y a pas de ligne avec le même nom et un champ null delete_at avant d'autoriser la restauration.
Vous pouvez en fait implémenter toute cette logique dans la base de données en utilisant un déclencheur INSTEAD-OF pour la suppression. Ce déclencheur ne supprimerait pas les enregistrements mais mettrait à jour la colonne delete_at lorsque vous supprimeriez un enregistrement.
L'exemple de code suivant le démontre
CREATE TABLE swtest (
id INT IDENTITY,
name NVARCHAR(20),
deleted_at DATETIME
)
GO
CREATE TRIGGER tr_swtest_delete ON swtest
INSTEAD OF DELETE
AS
BEGIN
UPDATE swtest SET deleted_at = getDate()
WHERE id IN (SELECT deleted.id FROM deleted)
AND deleted_at IS NULL -- Required to prevent duplicates when deleting already deleted records
END
GO
CREATE UNIQUE INDEX ix_swtest1 ON swtest(name, deleted_at)
INSERT INTO swtest (name) VALUES ('Thingy1')
INSERT INTO swtest (name) VALUES ('Thingy2')
DELETE FROM swtest WHERE id = SCOPE_IDENTITY()
INSERT INTO swtest (name) VALUES ('Thingy2')
DELETE FROM swtest WHERE id = SCOPE_IDENTITY()
INSERT INTO swtest (name) VALUES ('Thingy2')
SELECT * FROM swtest
DROP TABLE swtest
La sélection de cette requête renvoie ce qui suit
id name deleted_at 1 Thingy1 NULL 2 Thingy2 2009-04-21 08:55:38.180 3 Thingy2 2009-04-21 08:55:38.307 4 Thingy2 NULL
Ainsi, dans votre code, vous pouvez supprimer des enregistrements à l'aide d'une suppression normale et laisser le déclencheur s'occuper des détails. Le seul problème possible (que j'ai pu voir) était que la suppression d'enregistrements déjà supprimés pouvait entraîner des lignes en double, d'où la condition dans le déclencheur de ne pas mettre à jour le champ delete_at sur une ligne déjà supprimée.