Что не так с моим проверочным ограничением Oracle 10gr2? Попытка применить диапазон дат

Я хочу применить ограничение CHECK для диапазона дат, чтобы все даты в столбце BIRTH_DATE были меньше, чем завтра, и больше или равны 100 лет назад. Я попробовал это выражение в ограничении CHECK:

BIRTH_DATE >= (sysdate - numtoyminterval(100, 'YEAR')) AND BIRTH_DATE < sysdate + 1

Но я получил сообщение об ошибке «ORA-02436: дата или системная переменная неверно указаны в ограничении CHECK».

Есть ли способ сделать это, используя ограничение CHECK вместо триггера?


person Sajee    schedule 16.10.2008    source источник


Ответы (2)


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

Условия проверочных ограничений не могут содержать следующие конструкции:

* Subqueries and scalar subquery expressions
* Calls to the functions that are not deterministic (CURRENT_DATE,

CURRENT_TIMESTAMP, DBTIMEZONE, LOCALTIMESTAMP, SESSIONTIMEZONE, SYSDATE, SYSTIMESTAMP, UID, USER и USERENV)

person Justin Cave    schedule 16.10.2008

Что касается того, почему Oracle делает это ограничение: проверочные ограничения всегда должны оцениваться как TRUE, даже для обновлений. Если вы добавили в базу данных 99-летнего человека, а затем попытались обновить адрес электронной почты этого человека (например) через 2 года, вы получите нарушение контрольного ограничения.

Что вы могли бы сделать, если это уместно, так это иметь другой столбец CREATED_DATE, который по умолчанию равен SYSDATE, и сделать ограничение:

BIRTH_DATE >= (CREATED_DATE - numtoyminterval(100, 'YEAR')) 
AND BIRTH_DATE < CREATED_DATE + 1

Однако, если вы действительно хотите выполнять проверку только во время INSERT, сделайте это в триггере базы данных или в коде API.

person Tony Andrews    schedule 16.10.2008
comment
Предпочитайте решение API в базе данных, а не решение триггера. Триггеры следует использовать только в случае крайней необходимости. - person Leigh Riffel; 22.10.2008