Unique value Constraint with multiple columns across table,不是Oracle中的组合
Unique value Constraint with multiple columns across the table, not the combination in Oracle
在 oracle 中有没有办法强制两列之间的唯一性?
它不是两列组合之间的唯一性,而是两列之间 table 的值。
参考文献:
不应允许的示例数据:
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
我会结合检查约束和函数的唯一索引来解决它:
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));
案例 1 有效:
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
案例三,还有:
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);
我会使用 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)
这样的元组。
insert into mytable values(1, 111, 111);
ORA-02290: check constraint (FIDDLE_SMBYKTEIHNNVOHKZSCYK.SYS_C0020876) violated
begin
insert into mytable values(1, 111, null);
insert into mytable values(1, 111, null);
end;
/
ORA-00001: unique constraint (FIDDLE_SMBYKTEIHNNVOHKZSCYK.MYIDX) violated
ORA-06512: at line 3
begin
insert into mytable values(1, 111, null);
insert into mytable values(1, null, 111);
end;
/
ORA-00001: unique constraint (FIDDLE_SMBYKTEIHNNVOHKZSCYK.MYIDX) violated
ORA-06512: at line 3
begin
insert into mytable values(1, 111, 222);
insert into mytable values(1, 222, 111);
end;
/
ORA-00001: unique constraint (FIDDLE_SMBYKTEIHNNVOHKZSCYK.MYIDX) violated
ORA-06512: at line 3
在 oracle 中有没有办法强制两列之间的唯一性?
它不是两列组合之间的唯一性,而是两列之间 table 的值。
参考文献:
不应允许的示例数据:
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
我会结合检查约束和函数的唯一索引来解决它:
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));
案例 1 有效:
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
案例三,还有:
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);
我会使用 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)
这样的元组。
insert into mytable values(1, 111, 111);
ORA-02290: check constraint (FIDDLE_SMBYKTEIHNNVOHKZSCYK.SYS_C0020876) violated
begin
insert into mytable values(1, 111, null);
insert into mytable values(1, 111, null);
end;
/
ORA-00001: unique constraint (FIDDLE_SMBYKTEIHNNVOHKZSCYK.MYIDX) violated ORA-06512: at line 3
begin
insert into mytable values(1, 111, null);
insert into mytable values(1, null, 111);
end;
/
ORA-00001: unique constraint (FIDDLE_SMBYKTEIHNNVOHKZSCYK.MYIDX) violated ORA-06512: at line 3
begin
insert into mytable values(1, 111, 222);
insert into mytable values(1, 222, 111);
end;
/
ORA-00001: unique constraint (FIDDLE_SMBYKTEIHNNVOHKZSCYK.MYIDX) violated ORA-06512: at line 3