Możesz dodać wartość id na końcu nazwy, gdy rekord jest usuwany, więc gdy ktoś usunie id 3, nazwa staje się Thingy3_3, a gdy usunie id 100, imię staje się Thingy3_100. Umożliwiłoby to utworzenie unikalnego indeksu złożonego dla nazwy i usuniętych pól, ale wtedy musisz filtrować kolumnę nazwy za każdym razem, gdy ją wyświetlasz i usuwając identyfikator z końca nazwy.
Być może lepszym rozwiązaniem byłoby zastąpienie usuniętej kolumny kolumną delete_at typu DATETIME. Można wtedy zachować unikalny indeks nazwy i usunąć o, z nieusuniętym rekordem mającym wartość null w polu usunięty_at. Uniemożliwiłoby to tworzenie wielu nazw w stanie aktywnym, ale umożliwiłoby wielokrotne usuwanie tej samej nazwy.
Oczywiście musisz przeprowadzić test podczas przywracania rekordu, aby upewnić się, że nie ma wiersza o tej samej nazwie i pustego pola delete_at przed zezwoleniem na cofnięcie usunięcia.
W rzeczywistości można zaimplementować całą tę logikę w bazie danych, używając wyzwalacza INSTEAD-OF do usuwania. Ten wyzwalacz nie usunie rekordów, ale zamiast tego zaktualizuje kolumnę delete_at po usunięciu rekordu.
Poniższy przykładowy kod demonstruje to
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
Wybór z tego zapytania zwraca następujące
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
Tak więc w swoim kodzie możesz usuwać rekordy przy użyciu normalnego usuwania i pozwolić wyzwalaczowi zająć się szczegółami. Jedynym możliwym problemem (który mogłem zobaczyć) było to, że usunięcie już usuniętych rekordów może spowodować zduplikowanie wierszy, stąd warunek w regule, aby nie aktualizować pola delete_at w już usuniętym wierszu.