Puede agregar el valor de identificación al final del nombre cuando se elimina un registro, por lo que cuando alguien elimina la identificación 3, el nombre se convierte en Thingy3_3 y luego, cuando elimina la identificación 100, el nombre se convierte en Thingy3_100. Esto le permitiría crear un índice compuesto único en el nombre y los campos eliminados, pero luego debe filtrar la columna de nombre cada vez que la muestre y eliminar la identificación del final del nombre.
Quizás una mejor solución sería reemplazar su columna eliminada con una columna delete_at de tipo DATETIME. Luego, podría mantener un índice único en el nombre y eliminarlo en, con un registro no eliminado que tenga un valor nulo en el campo delete_at. Esto evitaría la creación de varios nombres en un estado activo, pero le permitiría eliminar el mismo nombre varias veces.
Obviamente, debe hacer una prueba al recuperar un registro para asegurarse de que no haya una fila con el mismo nombre y un campo delete_at nulo antes de permitir la recuperación.
De hecho, podría implementar toda esta lógica dentro de la base de datos utilizando un activador INSTEAD-OF para la eliminación. Este activador no eliminaría registros, sino que actualizaría la columna delete_at cuando eliminara un registro.
El siguiente código de ejemplo demuestra esto
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 selección de esta consulta devuelve lo siguiente
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
Entonces, dentro de su código, puede eliminar registros usando una eliminación normal y dejar que el disparador se encargue de los detalles. El único problema posible (que pude ver) era que eliminar registros ya eliminados podría dar como resultado filas duplicadas, por lo tanto, la condición en el disparador para no actualizar el campo delete_at en una fila ya eliminada.