Skip to Main Content
  • Questions
  • If one column is not null then another column should be not null, both can be nulls

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, ravi.

Asked: June 26, 2008 - 12:45 pm UTC

Last updated: June 27, 2008 - 9:59 am UTC

Version: 10.2.0

Viewed 10K+ times! This question is

You Asked

Hi Tom,

My requirement is : If col1 is having a value then col2 should have a value and vice versa. Also the combination of col1, col2 should be unique.

Both the columns can be null.

I am trying to create a unique index on the combination of these but, I am not sure how to mention it in the index using CASE. Can you please advise.

CREATE TABLE t (col1 VARCHAR2(1),col2 NUMBER(5));

CREATE UNIQUE INDEX ix_t
ON t (CASE WHEN col1 is not null THEN col2 ELSE NULL END);

CREATE UNIQUE INDEX ix_t
ON t (CASE WHEN col2 is not null THEN col1 ELSE NULL END);

INSERT INTO t (col1, col2) VALUES (null, null);

INSERT INTO t (col1, col2) VALUES ('X', null);

Thanks,
Ravi

and Tom said...

simple check constraint, nothing fancy needed

ops$tkyte%ORA9IR2> CREATE TABLE t
  2  (col1 VARCHAR2(1),
  3   col2 varchar2(1),
  4   constraint my_check check ( (col1 is null AND col2 is null) or (col1 is not null AND col2 is not null) )
  5  );

Table created.

ops$tkyte%ORA9IR2>
ops$tkyte%ORA9IR2> INSERT INTO t (col1, col2) VALUES (null, null);

1 row created.

ops$tkyte%ORA9IR2> INSERT INTO t (col1, col2) VALUES ('X', null);
INSERT INTO t (col1, col2) VALUES ('X', null)
*
ERROR at line 1:
ORA-02290: check constraint (OPS$TKYTE.MY_CHECK) violated


ops$tkyte%ORA9IR2> INSERT INTO t (col1, col2) VALUES (null, 'X');
INSERT INTO t (col1, col2) VALUES (null, 'X')
*
ERROR at line 1:
ORA-02290: check constraint (OPS$TKYTE.MY_CHECK) violated


ops$tkyte%ORA9IR2> INSERT INTO t (col1, col2) VALUES ('X', 'X');

1 row created.


Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

If one column is not null then another column should be not null, both can be nulls

ravi, June 27, 2008 - 9:24 am UTC

Thanks Tom, you always rock !!

I was thinking in the unique index direction. Just for learning, is it possible to implement the same using a unique index ?

Long live "Tom Kyte".

Thanks,
Ravi.
Tom Kyte
June 27, 2008 - 9:29 am UTC

using a unique index for this would not make sense - I don't see any possible connection between the rule:

c1 and c2 are either
both null
both not null

and the concept of

uniqueness


even if it "could be done", it would be the wrong way - we need not store anything extra here, we just need this rule to fire on the row - which it is - and we are done.

If one column is not null then another column should be not null, both can be nulls

ravi, June 27, 2008 - 9:48 am UTC

Hi Tom,

(sorry, overlooked the following before posting the earlier reponse).

"Also the combination of col1, col2 should be unique."

INSERT INTO t (col1, col2) VALUES ('X', 'X')
> 1 rows inserted

INSERT INTO t (col1, col2) VALUES ('X', 'X')
> 1 rows inserted

Please advise.
Thanks,
Ravi
Tom Kyte
June 27, 2008 - 9:59 am UTC

that is just then

alter table t add constraint c1_c2_unique unique(c1,c2);


If one column is not null then another column should be not null, both can be nulls

ravi, June 27, 2008 - 10:36 am UTC

Thanks Tom, much appreciated.

Long live "Tom Kyte".