Уникальное ограничение на любую комбинацию из двух столбцов - PullRequest
0 голосов
/ 28 июня 2018

Я пытаюсь реализовать уникальное ограничение для комбинации двух столбцов. Я бегу оракулом 11 г.

В частности, у меня есть две колонки A и B.

У меня есть строка, как показано ниже

A     B
1     2

Тогда я хочу, чтобы следующие комбинации не работали при вставке

A     B
1     2
2     1

Этого можно достичь с помощью уникального индекса в Oracle?

Ответы [ 2 ]

0 голосов
/ 28 июня 2018

Вы можете использовать UNIQUE INDEX с функциями LEAST, GREATEST и COALESCE:

CREATE TABLE table_name (
  a INT,
  b INT
);

CREATE UNIQUE INDEX table_name__a__b__u ON TABLE_NAME(
  COALESCE( LEAST( a, b ), a, b ),
  GREATEST( a, b )
);

Вам необходимо включить COALESCE в случае, если одно из значений NULL.

DBFiddle

INSERT INTO table_name ( a, b ) VALUES ( 1, 2 );
1 rows affected
INSERT INTO table_name ( a, b ) VALUES ( 3, NULL );
1 rows affected
INSERT INTO table_name ( a, b ) VALUES ( 2, 1 );
ORA-00001: unique constraint (SCHEMA_NAME.TABLE_NAME__A__B__U) violated
INSERT INTO table_name ( a, b ) VALUES ( NULL, 3 );
ORA-00001: unique constraint (SCHEMA_NAME.TABLE_NAME__A__B__U) violated
0 голосов
/ 28 июня 2018

Да, это возможно (например, с использованием сгенерированных столбцов):

CREATE TABLE tab(A INT NOT NULL, B INT NOT NULL);

ALTER TABLE tab ADD c1 AS (LEAST(A,B));
ALTER TABLE tab ADD c2 AS (GREATEST(A,B));
CREATE UNIQUE INDEX UQ_tab ON tab(c1,c2);

При необходимости вы можете скрыть эти столбцы (Oracle 12c):

ALTER TABLE tab MODIFY c1 INVISIBLE;
ALTER TABLE tab MODIFY c2 INVISIBLE;

Демоверсия DBFiddle

EDIT:

Еще более простой подход:

CREATE UNIQUE INDEX UQ_tab ON tab(least(A,B), greatest(A,B));

DBFiddle Demo

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...