What to do when I want to use database constraints but only mark as deleted instead of deleting?

后端 未结 10 1083
野的像风
野的像风 2020-12-31 20:55

I am working in a project where database items are not deleted, but only marked as deleted. Something like this:

id   name     deleted
---  -------  --------         


        
10条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-31 21:38

    The type of constraint you require is a table-level CHECK constraint i.e. a CHECK constraint consisting of a subquery which tests NOT EXISTS (or equivalent) for the table e.g.

    CREATE TABLE Test 
    (
       ID INTEGER NOT NULL UNIQUE, 
       name VARCHAR(30) NOT NULL, 
       deleted INTEGER NOT NULL, 
       CHECK (deleted IN (0, 1))
    );
    
    ALTER TABLE Test ADD
       CONSTRAINT test1__unique_non_deleted
          CHECK 
          (
             NOT EXISTS 
             (
                SELECT T1.name
                  FROM Test AS T1
                 WHERE T1.deleted = 0
                 GROUP
                    BY T1.Name
                HAVING COUNT(*) > 1
             )
          );
    
    INSERT INTO Test (ID, name, deleted) VALUES (1, 'Thingy1', 0)
    ;
    INSERT INTO Test (ID, name, deleted) VALUES (2, 'Thingy2', 0)
    ;
    INSERT INTO Test (ID, name, deleted) VALUES (3, 'Thingy3', 1)
    ;
    INSERT INTO Test (ID, name, deleted) VALUES (4, 'Thingy3', 1)
    ;
    INSERT INTO Test (ID, name, deleted) VALUES (5, 'Thingy3', 0)
    ;
    INSERT INTO Test (ID, name, deleted) VALUES (6, 'Thingy3', 0)
    ;
    

    The last INSERT (ID = 6) will cause the constraint to bite and the INSERT will fail. Q.E.D.

    ...ooh, nearly forgot to mention: SQL Server doesn't yet support CHECK constraints with that contain a subquery (I tested the above on ACE/JET, a.k.a. ). While you could use a FUNCTION I've read this is unsafe due to SQL Server testing constraints on a row-by-row basis (see David Portas' Blog). Until this full SQL-92 feature is supported in SQL Server, my preferred workaround is to use the same logic in a trigger.

提交回复
热议问题