唯一值约束,全表有多列,不是Oracle中的组合。

问题描述 投票:0回答:2

在oracle中,有没有一种方法可以在两列之间执行唯一性?

它不是两列组合之间的唯一性,而是两列之间跨表的值。

参考文献

多列间的唯一值约束

例数据,不应允许。

id | phone1 | phone2
1  | 111    | 111

id | phone1 | phone2
1  | 111    | NULL
2  | 111    | NULL  

id | phone1 | phone2
1  | 111    | NULL
2  | NULL   | 111 

两列组合的唯一约束?

我的Oracle版本。

Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
sql oracle multiple-columns unique-constraint
2个回答
2
投票

我会使用 check() 约束来确保每行的统一性,并为跨行的统一性建立唯一索引。

create table mytable (
    id int, 
    phone1 int, 
    phone2 int,
    check (phone1 <> phone2)
);

create unique index myidx on mytable(
    greatest(coalesce(phone1, phone2), coalesce(phone2, phone1)),
    least(coalesce(phone1, phone2), coalesce(phone2, phone1))
);

这种方法的好处是它还能防止插入像这样的元组 (111, 222)(222, 111).

DB Fiddle上的演示:

insert into mytable values(1, 111, 111);
ORA-02290:违反检查约束条件(FIDDLE_SMBYKTEIHNNVOHKZSCYK.SYS_C0020876)
begin
    insert into mytable values(1, 111, null);
    insert into mytable values(1, 111, null);
end;
/
ORA-00001:违反了唯一约束(FIDDLE_SMBYKTEIHNNVOHKZSCYK.MYIDX)ORA-06512:在第3行。
begin
    insert into mytable values(1, 111, null);
    insert into mytable values(1, null, 111);
end;
/
ORA-00001:违反了唯一约束(FIDDLE_SMBYKTEIHNNVOHKZSCYK.MYIDX)ORA-06512:在第3行。
begin
    insert into mytable values(1, 111, 222);
    insert into mytable values(1, 222, 111);
end;
/
ORA-00001:违反了唯一约束(FIDDLE_SMBYKTEIHNNVOHKZSCYK.MYIDX)ORA-06512:在第3行。

1
投票

我会用检查约束和函数上的唯一索引组合来解决。

CREATE TABLE t(id NUMBER, phone1 NUMBER, phone2 NUMBER);
ALTER  TABLE t ADD CONSTRAINT c1 CHECK (phone1 <> phone2);
CREATE UNIQUE INDEX u ON t(COALESCE(phone1, phone2));

情况一可行

INSERT INTO t VALUES (1, 111, 111);
ORA-02290: check constraint (C1) violated

情况2也可以

INSERT INTO t VALUES (1, 111, NULL);
INSERT INTO t VALUES (2, 111, NULL);
ORA-00001: unique constraint (U) violated

情况3也可以

INSERT INTO t VALUES (1, 111, NULL);
INSERT INTO t VALUES (2, NULL, 111);
ORA-00001: unique constraint (WFL.U) violated

然而,这是不受保护的。

INSERT INTO t VALUES (1, 111, 222);
INSERT INTO t VALUES (2, 222, 111);
© www.soinside.com 2019 - 2024. All rights reserved.