Используя дату в контрольном ограничении, Oracle

Я пытаюсь проверить добавление следующего ограничения, но Oracle возвращает ошибку, показанную ниже.

ALTER TABLE Table1 ADD (CONSTRAINT GT_Table1_CloseDate CHECK (CloseDate > SYSDATE), CONSTRAINT LT_Table1_CloseDate CHECK (CloseDate  (CloseDate + (SYSDATE + 730)))); 

Ошибка:

 Error report: SQL Error: ORA-02436: date or system variable wrongly specified in CHECK constraint 02436. 00000 - "date or system variable wrongly specified in CHECK constraint" *Cause: An attempt was made to use a date constant or system variable, such as USER, in a check constraint that was not completely specified in a CREATE TABLE or ALTER TABLE statement. For example, a date was specified without the century. *Action: Completely specify the date constant or system variable. Setting the event 10149 allows constraints like "a1 > '10-MAY-96'", which a bug permitted to be created before version 8. 

6 Solutions collect form web for “Используя дату в контрольном ограничении, Oracle”

К сожалению, ограничение проверки не может ссылаться на функцию типа SYSDATE. Вам потребуется создать триггер, который проверял эти значения, когда происходит DML, т. Е.

 CREATE OR REPLACE TRIGGER trg_check_dates BEFORE INSERT OR UPDATE ON table1 FOR EACH ROW BEGIN IF( :new.CloseDate < = SYSDATE ) THEN RAISE_APPLICATION_ERROR( -20001, 'Invalid CloseDate: CloseDate must be greater than the current date - value = ' || to_char( :new.CloseDate, 'YYYY-MM-DD HH24:MI:SS' ) ); END IF; IF( :new.CloseDate > add_months(SYSDATE,12) ) THEN RAISE_APPLICATION_ERROR( -20002, 'Invalid CloseDate: CloseDate must be within the next year - value = ' || to_char( :new.CloseDate, 'YYYY-MM-DD HH24:MI:SS' ) ); END IF; IF( :new.StartDate < = add_months(:new.CloseDate,24) ) THEN RAISE_APPLICATION_ERROR( -20002, 'Invalid StartDate: StartDate must be within 24 months of the CloseDate - StartDate = ' || to_char( :new.StartDate, 'YYYY-MM-DD HH24:MI:SS' ) || ' CloseDate = ' || to_char( :new.CloseDate , 'YYYY-MM-DD HH24:MI:SS' ) ); END IF; END; 

Вы не можете использовать SYSDATE в контрольном ограничении. Согласно документации

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

  • Подзапросы и выражения скалярного подзапроса
  • Вызывает функции, которые не являются детерминированными (CURRENT_DATE,
    CURRENT_TIMESTAMP, DBTIMEZONE,
    LOCALTIMESTAMP, SESSIONTIMEZONE,
    SYSDATE , SYSTIMESTAMP, UID, USER и USERENV)
  • Вызов пользовательских функций
  • Выделение столбцов REF (например, с использованием функции DEREF)
  • Вложенные столбцы или атрибуты таблицы
  • Псевдоколонны CURRVAL, NEXTVAL, LEVEL или ROWNUM
  • Константы даты, которые не указаны полностью

Для 10g Release 2 (10.2) см. Ограничение, а для 11g Release 2 (11.2) см. Ограничение .

Помните, что ограничение целостности – это утверждение о табличных данных, которое всегда верно.

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

Каждый раз, когда запись обновляется, SYSDATE будет иметь другое значение. Поэтому ограничение будет проверять по-разному каждый раз. По этой причине Oracle не разрешает sysdate в ограничении.

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

И: Что такое (StartDate > (CloseDate + (SYSDATE + 730)))) ? Вы не можете добавлять даты.

И: StartDate должен быть после CloseDate ? Разве это не странно?

Запишите sysdate в столбец и используйте его для проверки. Этот столбец может быть вашим столбцом аудита (например, дата создания)

 CREATE TABLE "AB_EMPLOYEE22" ( "NAME" VARCHAR2 ( 20 BYTE ), "AGE" NUMBER, "SALARY" NUMBER, "DOB" DATE, "DOJ" DATE DEFAULT SYSDATE ); Table Created ALTER TABLE "AB_EMPLOYEE22" ADD CONSTRAINT AGE_CHECK CHECK((ROUND((DOJ-DOB)/365)) = AGE) ENABLE; Table Altered 

Вы можете добиться этого, когда будете немного обманывать:

 CREATE OR REPLACE FUNCTION SYSDATE_DETERMINISTIC RETURN DATE DETERMINISTIC IS BEGIN RETURN SYSDATE; END SYSDATE_DETERMINISTIC; / CREATE TABLE Table1 ( s_date DATE, C_DATE DATE GENERATED ALWAYS AS ( SYSDATE_DETERMINISTIC() ) ); ALTER TABLE Table1 ADD CONSTRAINT s_check CHECK ( s_date < C_DATE ); 

Конечно, функция SYSDATE_DETERMINISTIC не является детерминированной, но Oracle позволяет объявить это в любом случае.

Возможно, в будущих выпусках Oracle станет более умным и больше не позволит таких трюков.

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

  ALTER TABLE Table1 ADD (REGISTER_DATE DATE); CREATE OR REPLACE TRIGGER trg_check_dates BEFORE INSERT OR UPDATE ON table1 FOR EACH ROW BEGIN :new.REGISTER_DATE := SYSDATE; END; ALTER TABLE Table1 ADD (CONSTRAINT GT_Table1_CloseDate CHECK (CloseDate > REGISTER_DATE), CONSTRAINT LT_Table1_CloseDate CHECK (CloseDate < = REGISTER_DATE + 365)), CONSTRAINT GT_Table1_StartDate CHECK (StartDate > (CloseDate + (REGISTER_DATE + 730)))); 
Interesting Posts

Использование библиотек C для программ на C ++

Как отформатировать Ext2 в Windows XP?

MVC, кнопка отправки которого нажата

Как получить полное дерево каталогов с помощью SPL?

Соображения производительности для keySet () и entrySet () карты

Как поместить метки над geom_bar для каждого бара в R с помощью ggplot2

Является ли порядок значений, полученных из HashMap, порядком размещения

Как установить Linux на динамический диск без потери конфигурации диска?

Экран ноутбука Acer не запускается, если я не нажму fn + f4

расчет високосного года

Извлечение нескольких разделов страниц из pdf

Что еще важнее CPU или ОЗУ для компиляции большого программного обеспечения, например, bootstrapping gcc?

BSOD «STOP 0x0000007B» после установки WIndows XP на внешний жесткий диск

Chmod для разрешения на чтение и запись для каталога

Отключить функциональность восстановления сеанса Google Chrome

Давайте будем гением компьютера.