Oracle: условное ненулевое ограничение, когда оба условия выполняются - PullRequest
0 голосов
/ 18 декабря 2018

Мне нужно изменить таблицу, чтобы создать условное ненулевое ограничение для определенного столбца, чтобы оно не могло быть нулевым, если значения col1 и col2 имеют значения.

Во-первых, что такое условное ненулевое ограничение?

Во-вторых, не могли бы вы предоставить синтаксис о том, как этого добиться?

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Предикат, который вам нужно проверить:

if (col1 is not null and col2 is not null) then specific is not null

Предикат if A then B можно записать как not A or B

Обратите внимание, что приоритет равен (not A) or B см. Обсуждение здесь

Таким образом, вы получаете:

alter table spec add constraint my_spec
check (not (col1 is not null and col2 is not null) or specific is not null);

, если col1 или col2 равны нулю, spcific обнуляется

insert into spec(col1,col2,specific) values(null,null,null);
insert into spec(col1,col2,specific) values(1,null,null);
insert into spec(col1,col2,specific) values(null,1,null);

, если и col1, и col2 определены как секретныев NOT NULL

insert into spec(col1,col2,specific) values(1,1,1);
insert into spec(col1,col2,specific) values(1,1,null);
-- ORA-02290: check constraint (REPORTER.MY_SPEC) violated

В существующую таблицу вы можете добавить это check, только если существующие данные полностью заполнят проверку, в противном случае вы получите это исключение

 ORA-02293: cannot validate (OWNER.MY_SPEC) - check constraint violated

Чтобы найти строки, которыенарушил новое правило, просто запрос

 select * from spec
 where NOT (not (col1 is not null and col2 is not null) or specific is not null);

Вы должны либо удалить эти строки, либо установить specific в ненулевое значение, либо установить col1 или col2 в NULL.

В качестве альтернативы Вы можете активировать ограничение с помощью опции NOVALIDATE, это допускает существующие нарушения, но обеспечивает, чтобы новые изменения следовали ограничению.

alter table spec add constraint my_spec
check (not (col1 is not null and col2 is not null) or specific is not null)
enable novalidate;
0 голосов
/ 18 декабря 2018

Это звучит как ограничение check:

alter table t add constraint chk_t_specific
    check ( (col1 is null) or (col2 is null) or (specific is not null) );

Это также можно записать как:

alter table t add constraint chk_t_specific
    check (not ( (col1 is not null) and 
                 (col2 is not null) and
                 (specific is null)
               ) 
          );

Если это поможет вам лучше следовать логике.

Это дает значение false только при следующих условиях:

  • col1 не равно нулю (т. Е. col1 имеет значение)
  • col2 не равно нулю (т. е. col2 имеет значение)
  • specific равно нулю

Это именно то условие, которое ОП хочет отфильтровать.

НаВ существующей таблице вы можете увидеть, какие строки нарушили ограничение:

select *
from t
where col1 is not null and col2 is not null and specific is null;

Если какие-либо строки нарушили ограничение, вам необходимо исправить их перед добавлением ограничения.

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