带表达式的Oracle唯一约束

JAR*_*ARC 9 sql oracle oracle10g

是否Oracle支持带有这样表达式的约束?

注意Z ='N'

ALTER TABLE A ADD CONSTRAINT U_A_KEY UNIQUE(X,Y,Z = 'N');
Run Code Online (Sandbox Code Playgroud)

Unique constraint可能吗?

例:

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
Run Code Online (Sandbox Code Playgroud)

Ren*_*ger 19

也许这给了一个主意

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
);
Run Code Online (Sandbox Code Playgroud)

后来:

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');
Run Code Online (Sandbox Code Playgroud)

最后一个抛出:

ORA-00001: unique constraint (SPEZMDBA.TQ84_N_X) violated
Run Code Online (Sandbox Code Playgroud)


Jus*_*ave 6

在这种情况下,最简单的方法通常是创建基于函数的索引.就像是

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) );
Run Code Online (Sandbox Code Playgroud)

如果z不是'N',则两个CASE语句都计算为NULL,而Oracle不必将x和y值存储在索引结构中(使索引更小).如果z为'N',则x和y值都存储在索引中,并且索引的行为与任何其他复合索引一样.