开发者

Oracle Unique Constraint with Expression

Does Oracle support constraints with expressions like so?

Notice Z = 'N'

ALTER TABLE A ADD CONSTRAINT U_A_KEY UNIQUE(X,Y,Z = 'N');

Is this Unique constraint possible?

Example:

开发者_JS百科
INSERT INTO A VALUES('X','Y','N');  --OK
INSERT INTO A VALUES('X','Y','Y');  --OK
INSERT INTO A VALUES('X','Y','Y');  --OK
INSERT INTO A VALUES('X','Y','N');  --VOLIATION


Maybe this gives an idea

drop table tq84_n;

create table tq84_n (
   x number, 
   y number, 
   z varchar2(10)
);

create unique index tq84_n_x on tq84_n (
  case when z = 'N' then x || '-' || y 
       else null
  end
);

Later:

insert into tq84_n values (4,5, 'N');

insert into tq84_n values (9,6, 'Y');
insert into tq84_n values (9,6, 'Y');

insert into tq84_n values (4,5, 'Y');

insert into tq84_n values (4,5, 'N');

Last one throws:

ORA-00001: unique constraint (SPEZMDBA.TQ84_N_X) violated


The simplest approach in this case is generally to create a function based index. Something like

CREATE UNIQUE INDEX u_a_key
    ON a( (CASE WHEN z = 'N' THEN x ELSE null END),
          (CASE WHEN z = 'N' THEN y ELSE null END) );

If z is not 'N', both CASE statements evaluate to NULL and Oracle doesn't have to store the x & y values in the index structure (making the index smaller). If z is 'N', the x & y values are both stored in the index and the index behaves just like any other compound index.


What I do in that sitaution is to create a column e.g. Z in your case, which has:

  • A particular value (e.g. your "N") in the case I need it to be unique
  • Null otherwise, meaning unknown: two unknown values are considered to be not equal to one another.

Then you can create your unique constraint UNIQUE(X,Y,Z).

Add two rows with equal X and Y and Z="N" and you'll get an error; add two rows with equal X and Y both with Z=null and you won't.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜