sql >> Databáze >  >> RDS >> Sqlserver

Co dělat, když chci použít omezení databáze, ale místo smazání pouze označit jako odstraněné?

Když je záznam odstraněn, můžete přidat hodnotu id na konec jména, takže když někdo odstraní id 3, jméno se změní na Thingy3_3 a poté, když odstraní id 100, se název změní na Thingy3_100. To by vám umožnilo vytvořit jedinečný složený index pro název a odstraněná pole, ale poté musíte sloupec názvu filtrovat, kdykoli jej zobrazíte, a odstranit id z konce názvu.

Možná by bylo lepším řešením nahradit odstraněný sloupec sloupcem delete_at typu DATETIME. Pak byste mohli udržovat jedinečný index pro jméno a smazaný na, s nesmazaným záznamem, který má v poli delete_at hodnotu null. To by zabránilo vytvoření více jmen v aktivním stavu, ale umožnilo by vám to stejné jméno několikrát smazat.

Při obnovování záznamu musíte samozřejmě provést test, abyste se ujistili, že neexistuje žádný řádek se stejným názvem a prázdným polem delete_at, než umožníte zrušení smazání.

Ve skutečnosti byste mohli implementovat veškerou tuto logiku v databázi pomocí spouštěče INSTEAD-OF pro odstranění. Tento spouštěč neodstraní záznamy, ale místo toho aktualizuje sloupec delete_at, když smažete záznam.

Následující příklad kódu to ukazuje

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ýběr z tohoto dotazu vrátí následující

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že v rámci svého kódu můžete mazat záznamy pomocí normálního mazání a nechat spouštěč, aby se postaral o podrobnosti. Jediný možný problém (který jsem viděl) byl ten, že smazání již smazaných záznamů by mohlo mít za následek duplicitní řádky, tedy podmínka ve spouštěči neaktualizovat pole delete_at na již smazaném řádku.



  1. Po zadání objednávky ve Woocommerce vložte hodnoty do vlastní tabulky

  2. Rozdíl MySql mezi dvěma časovými razítky v sekundách?

  3. Kdy se řazení SQL Server přetočí?

  4. Reprezentuje čas bez data v rubínu