Sie könnten den ID-Wert am Ende des Namens hinzufügen, wenn ein Datensatz gelöscht wird. Wenn also jemand die ID 3 löscht, wird der Name zu Thingy3_3, und wenn er dann die ID 100 löscht, wird der Name zu Thingy3_100. Dies würde es Ihnen ermöglichen, einen eindeutigen zusammengesetzten Index für den Namen und die gelöschten Felder zu erstellen, aber Sie müssen dann die Namensspalte jedes Mal filtern, wenn Sie sie anzeigen, und die ID am Ende des Namens entfernen.
Vielleicht wäre es eine bessere Lösung, Ihre gelöschte Spalte durch eine "deleted_at"-Spalte vom Typ DATETIME zu ersetzen. Sie könnten dann einen eindeutigen Index für „name“ und „delete at“ verwalten, wobei ein nicht gelöschter Datensatz einen Nullwert im Feld „deleted_at“ hat. Dies würde die Erstellung mehrerer Namen in einem aktiven Zustand verhindern, aber es Ihnen ermöglichen, denselben Namen mehrmals zu löschen.
Sie müssen natürlich einen Test durchführen, wenn Sie einen Datensatz wiederherstellen, um sicherzustellen, dass es keine Zeile mit demselben Namen und einem leeren Feld "delete_at" gibt, bevor Sie die Wiederherstellung zulassen.
Sie könnten diese gesamte Logik tatsächlich in der Datenbank implementieren, indem Sie einen INSTEAD-OF-Trigger für das Löschen verwenden. Dieser Trigger würde keine Datensätze löschen, sondern stattdessen die Spalte „deleted_at“ aktualisieren, wenn Sie einen Datensatz löschen.
Der folgende Beispielcode demonstriert dies
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
Die Auswahl aus dieser Abfrage gibt Folgendes zurück
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
In Ihrem Code können Sie also Datensätze mit einem normalen Löschvorgang löschen und den Trigger die Details erledigen lassen. Das einzig mögliche Problem (das ich sehen konnte) war, dass das Löschen bereits gelöschter Datensätze zu doppelten Zeilen führen konnte, daher die Bedingung im Trigger, das Feld "deleted_at" in einer bereits gelöschten Zeile nicht zu aktualisieren.