Du kan lägga till id-värdet i slutet av namnet när en post raderas, så när någon tar bort id 3 blir namnet Thingy3_3 och när de tar bort id 100 blir namnet Thingy3_100. Detta skulle tillåta dig att skapa ett unikt sammansatt index på namnet och borttagna fält, men du måste sedan filtrera namnkolumnen när du visar den och ta bort id:t från slutet av namnet.
En bättre lösning skulle kanske vara att ersätta din borttagna kolumn med en raderad_at kolumn av typen DATETIME. Du kan sedan upprätthålla ett unikt index på namn och raderade på, med en icke-raderad post som har ett nollvärde i deleted_at-fältet. Detta skulle förhindra skapandet av flera namn i ett aktivt tillstånd men skulle tillåta dig att radera samma namn flera gånger.
Du måste uppenbarligen göra ett test när du återställer en post för att säkerställa att det inte finns någon rad med samma namn och ett null deleted_at-fält innan du tillåter att du tar bort borttagningen.
Du kan faktiskt implementera all denna logik i databasen genom att använda en INSTEAD-OF-utlösare för borttagningen. Den här utlösaren skulle inte ta bort poster utan skulle istället uppdatera kolumnen deleted_at när du raderade en post.
Följande exempelkod visar detta
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
Välj från denna fråga returnerar följande
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
Så inom din kod kan du radera poster med en normal radering och låta triggern ta hand om detaljerna. Det enda möjliga problemet (som jag kunde se) var att radering av redan raderade poster kunde resultera i dubbletter av rader, därav villkoret i utlösaren att inte uppdatera fältet deleted_at på en redan raderad rad.