多列的唯一约束-允许单个null

Fer*_*ito 2 sql oracle

我发现了这一点:多列上的唯一约束

SQL> CREATE TABLE t (id1 NUMBER, id2 NUMBER);

Table created
SQL> ALTER TABLE t ADD CONSTRAINT u_t UNIQUE (id1, id2);

Table altered
SQL> INSERT INTO t VALUES (1, NULL);

1 row inserted
SQL> INSERT INTO t VALUES (1, NULL);

INSERT INTO t VALUES (1, NULL)

ORA-00001: unique constraint (VNZ.U_T) violated
Run Code Online (Sandbox Code Playgroud)

我想创建一个允许输入多个(X,null)值的约束,以便该约束仅在该约束所要的两个值都不为null时才起作用。这可能吗?

Tho*_*ner 5

请注意,您可以插入多个(NULL,NULL),但不能插入多个(1,NULL)。这就是索引在Oracle中的工作方式。当所有列均为空时,则索引中没有任何条目。

因此,与其建立在(id1,id2)上的普通索引,不如建立一个函数索引,当至少一个为null时,这两个值都为null。为此,我们需要确定性功能。首先进行DECODE以检查是否为空。然后使用GREATEST,并在至少一个值为null的情况下使用它,从而导致null:

create unique index idx_t_unique on t 
( 
  decode(greatest(id1,id2),null,null,id1), 
  decode(greatest(id1,id2),null,null,id2) 
);
Run Code Online (Sandbox Code Playgroud)

编辑(接受后:-)我只看到,您不需要确定性函数,但也可以使用用例构造。也许总是这样,也许不,我不知道。但是,如果您觉得索引更具可读性,也可以按如下方式编写索引:

create unique index idx_t_unique on t 
(
  case when id1 is null or id2 is null then null else id1 end,
  case when id1 is null or id2 is null then null else id2 end
);
Run Code Online (Sandbox Code Playgroud)