Sql Conditional Not Null Constraint Sql Conditional Not Null Constraint sql sql

Sql Conditional Not Null Constraint


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    ));


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 )


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 table1FOR EACH ROWWHEN (new.A = 'NEW' and new.B IS NOT NULL)   RAISE_APPLICATION_ERROR (     num=> -20001,     msg=> 'B must be NULL for new rows (A = NEW)');