带表达式的 Oracle 唯一约束

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4648371/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 22:24:16  来源:igfitidea点击:

Oracle Unique Constraint with Expression

sqloracleoracle10g

提问by JARC

Does Oraclesupport constraints with expressions like so?

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

Notice Z = 'N'

注意 Z = 'N'

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

Is this Unique constraintpossible?

Unique constraint可能吗?

Example:

例子:

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

回答by René Nyffenegger

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

回答by Justin Cave

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.

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

回答by Adrian Smith

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

在这种Z情况下,我所做的是创建一个列,例如在您的情况下,它具有:

  • 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.
  • 在我需要它是唯一的情况下的特定值(例如您的“N”)
  • 否则为空,表示未知:两个未知值被认为彼此不相等。

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

然后您可以创建您的唯一约束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.

将两行 X 和 Y 相等且 Z="N" 相加,你会得到一个错误;添加两行具有相等的 X 和 Y 并且 Z=null 并且你不会。