Sql Conditional Not Null Constraint

前端 未结 4 1158
臣服心动
臣服心动 2021-02-01 04:20


I am curious to know is it possible to create a conditional not null constraint in sql? In otherwords is it possible to create a constraint such that a column B can be null

相关标签:
4条回答
  • 2021-02-01 04:55

    I think your first stated requirement is:

    IF ( B IS NULL ) THEN ( A = 'NEW' )
    

    Apply the implication rewrite rule:

    IF ( X ) THEN ( Y )   <=>   ( NOT ( X ) OR ( Y ) )
    

    In your case;

    ( NOT ( B IS NULL ) OR ( A = 'NEW' ) )
    

    Minor rewrite to take advantage of SQL syntax:

    ( B IS NOT NULL OR A = 'NEW' )
    

    Your second stated ("extend") requirement:

    IF ( A = 'NEW' ) THEN ( B IS NULL )
    

    Apply rewrite rule:

    ( NOT ( A = 'NEW' ) OR ( B IS NULL ) )
    

    Minor rewrite:

    ( A <> 'NEW' OR B IS NULL )
    
    0 讨论(0)
  • 2021-02-01 04:59

    Edit: as mentioned in the other answers, a CHECK is the best method, not the trigger I originally suggested. Original text follows:


    As dbaseman suggests, triggers are the way to go (not so). Try something like this (untested):

    CREATE OR REPLACE TRIGGER test
      BEFORE UPDATE ON table1
    FOR EACH ROW
    WHEN (new.A = 'NEW' and new.B IS NOT NULL)
       RAISE_APPLICATION_ERROR (
         num=> -20001,
         msg=> 'B must be NULL for new rows (A = NEW)'
    );
    
    0 讨论(0)
  • 2021-02-01 05:10

    This is perfectly fine for CONSTRAINT CHECK. Just do this:

    Requirement:

    is it possible to create a constraint such that a column B can be null as long column A contains lets say 'NEW' but if the contents of column A changes to something else then column B is no longer allowed to be null?

    Note the phrase: column B can be null

    Solution:

    create table tbl
    (
        A varchar(10) not null,
        B varchar(10),
    
        constraint uk_tbl check
        (
          A = 'NEW' -- B can be null or not null: no need to add AND here
          OR (A <> 'NEW' AND B IS NOT NULL)
        )
    );
    

    You can simplify it further:

    create table tbl
    (
        A varchar(10) not null,
        B varchar(10),
    
        constraint uk_tbl check
        (
          A = 'NEW' 
          OR B IS NOT NULL
        )
    );
    

    Requirement mutually incompatible to requirement above:

    And to extend on that, it is then possible to make it so that column B must be null or empty as long as column A says 'NEW'?

    Note the phrase: column B must be null

    create table tbl
    (
        A varchar(10) not null,
        B varchar(10),
    
        constraint uk_tbl check
        (
          (A = 'NEW' AND B IS NULL)
          OR A <> 'NEW'
        )
    );
    

    Could be simplified with this, simpler but might not be as readable as above though:

    create table tbl
    (
        A varchar(10) not null,
        B varchar(10),
    
        constraint uk_tbl check
        (
          A <> 'NEW'
          OR B IS NULL
        )
    );
    
    0 讨论(0)
  • 2021-02-01 05:21

    Per onedaywhen, this answer is criminally wrong, and an abomination. You can use a CHECK constraint. http://msdn.microsoft.com/en-us/library/ms188258.aspx

    There's not a way to make conditional constraints. You should, however be able to do the job using a trigger. That's what they're for.

    http://msdn.microsoft.com/en-us/library/ms189799.aspx

    CREATE TRIGGER MyTable.ConditionalNullConstraint ON MyTable.ColumnB
    AFTER INSERT
    AS
    IF EXISTS (SELECT *
        FROM inserted
        WHERE A <> 'NEW' AND B IS NULL
        )
    BEGIN
        RAISERROR ('if A is ''NEW'' then B cannot be NULL', 16, 1);
        ROLLBACK TRANSACTION;
    END;
    GO
    

    Note that in the query you'll want to reference inserted which is a special object that behaves like a table, and lets you reference the row(s) that caused the trigger.

    Of course, in this example you'd need to handle AFTER UPDATE also to enforce the constraint, but that's the general idea.

    0 讨论(0)
提交回复
热议问题