sql >> Database teknologi >  >> RDS >> Sqlserver

Hvad skal jeg gøre, når jeg vil bruge databasebegrænsninger, men kun markere som slettet i stedet for at slette?

Du kan tilføje id-værdien til slutningen af ​​navnet, når en post slettes, så når nogen sletter id 3, bliver navnet Thingy3_3, og når de sletter id 100, bliver navnet Thingy3_100. Dette vil give dig mulighed for at oprette et unikt sammensat indeks på navnet og slettede felter, men du skal derefter filtrere navnekolonnen, når du viser den og fjerne id'et fra slutningen af ​​navnet.

Måske ville en bedre løsning være at erstatte din slettede kolonne med en deleted_at-kolonne af typen DATETIME. Du kan derefter opretholde et unikt indeks på navn og slettet på, med en ikke-slettet post med en nulværdi i deleted_at-feltet. Dette ville forhindre oprettelsen af ​​flere navne i en aktiv tilstand, men ville tillade dig at slette det samme navn flere gange.

Du skal naturligvis lave en test, når du fortryder sletningen af ​​en post for at sikre, at der ikke er nogen række med samme navn og et null deleted_at-felt, før du tillader annullering af sletning.

Du kunne faktisk implementere al denne logik i databasen ved at bruge en ISTEDEN AF-udløser til sletningen. Denne trigger ville ikke slette poster, men ville i stedet opdatere deleted_at-kolonnen, når du slettede en post.

Følgende eksempelkode viser dette

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  

Valget fra denne forespørgsel returnerer følgende

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å i din kode kan du slette poster ved at bruge en normal sletning og lade triggeren tage sig af detaljerne. Det eneste mulige problem (det jeg kunne se) var, at sletning af allerede slettede poster kunne resultere i dublerede rækker, derfor betingelsen i triggeren om ikke at opdatere deleted_at-feltet på en allerede slettet række.



  1. Mysql count ydeevne på meget store borde

  2. Kubernetes kopierer ikke data til monteret volumen

  3. Android Studio kan ikke finde eksplicit aktivitetsklasse

  4. SQL Server-forespørgsel:Hurtig med bogstavelig men langsom med variabel