Ограничение уникального значения с несколькими столбцами в таблице, а не комбинация в Oracle - PullRequest
1 голос
/ 08 мая 2020

В 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

Ответы [ 2 ]

2 голосов
/ 08 мая 2020

Я бы использовал ограничение 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: 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
1 голос
/ 08 мая 2020

Я бы решил это с помощью комбинации контрольного ограничения и уникального индекса функции:

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

Тоже случай 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...