Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do you enforce conditional not null check across sql columns

create table A (id, col_A, col_B, col_C)

id = unique id for every row being persisted either col_A or col_B will have a valid value, but both columns will not have a value for each persisted row at the same time.

e.g.

insert into A (id, col_A, col_C) values (1, "a", "c")
insert into A (id, col_B, col_C) values (1, "b", "c")
insert into A (id, col_A, col_C) values (1, "aa", "cc")
insert into A (id, col_B, col_C) values (1, "bb", "cc")

note: col_A and col_B cannot be merged into a single column as per design.

I would like to enforce conditional not null check across col_A and col_B based on the above restriction (i.e. for each row atleast col_A or col_B should be present). How do I acheive that?

EDIT:

  1. We would like to support the following databases to start with H2, MySQL, Postgres
  2. We would also like to express the constraints via JPA annotations instead of a database specific syntax
  3. The underlying ORM layer is Hibernate 3.3.x
like image 765
Joe Avatar asked Jan 15 '10 05:01

Joe


People also ask

How do you add not NULL constraint to multiple columns?

We can add NOT NULL constraint on multiple columns in one table. NOT NULL constraint allows duplicate values. If we defined a column as NOT NULL while inserting or updating values on table, we must and should give value to that specified column. Not Null Constraint allow duplicate values.

How do I select a record with no NULL values in SQL Server?

To display records without NULL in a column, use the operator IS NOT NULL. You only need the name of the column (or an expression) and the operator IS NOT NULL (in our example, the price IS NOT NULL ). Put this condition in the WHERE clause (in our example, WHERE price IS NOT NULL ), which filters rows.


2 Answers

You need to define a table level check constraint. The following uses Oracle syntax but most DBMS products will have something pretty similar....

alter table A add constraint a_or_b
    check (
        ( a is not null and b is null ) 
    or
        ( a is null and b is not null ) 
    )
/

edit

In response to your comment I guess it would be

@org.hibernate.annotations.Check(

constraints = “(a is not null and b is null) or (a is null and b is not null)”

)

But as a data modeller and a DBA this is really the sort of thing I would want enforced in the database. I don't think the syntax will really vary that much, if at all, across the different flavours of RDBMS.

like image 187
APC Avatar answered Nov 03 '22 01:11

APC


You can use a constraint that checks col_a is not null or col_b is not null. This will give you an error if both columns are null or if both columns are not null. It will only allow records with either a or b.

In SQL Server would be like:

ALTER TABLE [dbo].[A]  
WITH CHECK ADD  CONSTRAINT [CK_test] 
   CHECK  (([col_a] IS NOT NULL and [col_b] IS NULL)
        or ([col_a] IS NULL and [col_b] IS NOT NULL)
        )
like image 24
Jose Chama Avatar answered Nov 03 '22 00:11

Jose Chama