Условное ограничение - PullRequest
0 голосов
/ 30 ноября 2018

Я хотел бы реализовать ограничение для следующей таблицы:

CREATE TABLE GLOBAL_LOCKS 
( 
  RESOURCE_NAME VARCHAR2(50) NOT NULL, 
  IS_EXCLUSIVE CHAR(1) DEFAULT 'N' NOT NULL 
)

следующим образом:

  1. RESOURCE_NAME должно быть уникальным, если IS_EXLUSIVE = 'Y'
  2. RESOURCE_NAME может быть дубликатом, если все записи имеют IS_EXCLUSIVE = 'N'

--Example 1
INSERT INTO GLOBAL_LOCKS(RESOURCE_NAME, IS_EXCLUSIVE)
VALUES ('MY_RESOURCE', 'Y');
INSERT INTO GLOBAL_LOCKS(RESOURCE_NAME, IS_EXCLUSIVE)
VALUES ('MY_RESOURCE', 'N');
-- should fail

--Example 2
INSERT INTO GLOBAL_LOCKS(RESOURCE_NAME, IS_EXCLUSIVE)
VALUES ('MY_RESOURCE', 'N');
INSERT INTO GLOBAL_LOCKS(RESOURCE_NAME, IS_EXCLUSIVE)
VALUES ('MY_RESOURCE', 'N');
-- should work

--Example 3
INSERT INTO GLOBAL_LOCKS(RESOURCE_NAME, IS_EXCLUSIVE)
VALUES ('MY_RESOURCE', 'N');
INSERT INTO GLOBAL_LOCKS(RESOURCE_NAME, IS_EXCLUSIVE)
VALUES ('MY_RESOURCE', 'N');
INSERT INTO GLOBAL_LOCKS(RESOURCE_NAME, IS_EXCLUSIVE)
VALUES ('MY_RESOURCE', 'Y');
-- should fail

Идея состоит в том, чтобы поддерживать исключительные и общие блокировки в этой таблице и полагаться на ограничениеобеспечить целостность.Для данного ресурса может быть только одна исключительная блокировка;но для данного ресурса может быть несколько общих блокировок.

Этот вопрос похож на https://asktom.oracle.com/pls/apex/asktom.search?tag=how-to-enforce-conditional-unique-on-multiple-columns, но решение не работает для этого случая из-за требования # 1

1 Ответ

0 голосов
/ 30 ноября 2018

Это сложно, потому что ваше требование зависит не от значения какой-либо строки, а от конкретной комбинации строк.Я думаю, вам нужно будет создать материализованное представление и ограничение для этого mview.

create materialized view global_locks_validator
refresh force on commit as
select resource_name,
       max( case when is_exclusive = 'Y' then 1 else 0 end ) as max_is_exclusive,
       count(1) as resource_count
  from global_locks
 group by resource_name;

alter materialized view global_locks_validator add (
    constraint ck_validate check( max_is_exclusive = 0 or resource_count = 1 )
);

Недостаток этого метода заключается в том, что ограничение проверяется только при запуске commit.

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