带表达式的Oracle唯一约束

时间:2011-01-10 15:28:01

标签: sql oracle oracle10g

Oracle是否支持带有类似表达式的约束?

注意Z ='N'

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

这可能是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

3 个答案:

答案 0 :(得分: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
);

随后:

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

最后一个抛出:

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

答案 1 :(得分: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) );

如果z不是'N',则两个CASE语句都评估为NULL,Oracle不必存储x&索引结构中的y值(使索引更小)。如果z是'N',则x& y值都存储在索引中,索引的行为与任何其他复合索引一样。

答案 2 :(得分:0)

我在该情况下所做的是创建一个列,例如在您的情况下Z,其中包含:

  • 在我需要它是唯一的情况下的特定值(例如您的“N”)
  • 否则为空,意思是未知:两个未知值被认为彼此不相等。

然后您可以创建唯一约束UNIQUE(X,Y,Z)

添加两行,X和Y相等,Z =“N”,你会得到一个错误;添加两行,X和Y相等,Z = null,你不会。