Ограничения с использованием DATE

Я пытаюсь создать ограничение, чтобы проверить, что запись не больше 2016 года.

Вот запись в моей базе

введите здесь описание изображения

Вот мой запрос:

ALTER TABLE SIGHTINGS 
   ADD CONSTRAINT CK_SIGHTING_DATE 
   CHECK (SIGHTING_DATE <=TO_DATE('01-JAN-16'));

Но я получил сообщение об ошибке: ОШИБКА в строке 1:

ORA-02436: дата или системная переменная неправильно указаны в ограничении CHECK.

Я проверил некоторые подобные вопросы на этом веб-сайте, но решения не решают мою проблему.


person Sean Li    schedule 11.10.2016    source источник
comment
meta.stackoverflow.com/questions/285551/   -  person a_horse_with_no_name    schedule 11.10.2016


Ответы (2)


Один из вариантов — использовать функцию extract(), так как вы просто хотите проверить год:

ALTER TABLE SIGHTINGS 
   ADD CONSTRAINT CK_SIGHTING_DATE 
   CHECK (extract(year from SIGHTING_DATE) < 2016);

или используйте литерал даты ANSI:

ALTER TABLE SIGHTINGS 
   ADD CONSTRAINT CK_SIGHTING_DATE 
   CHECK (SIGHTING_DATE < date '2016-01-01');
person a_horse_with_no_name    schedule 11.10.2016
comment
Я пробовал оба варианта, но получаю эту ошибку: ORA-02293: невозможно проверить (S4369490.CK_SIGHTING_DATE) — нарушение ограничения проверки. - person Sean Li; 12.10.2016
comment
@SeanLi: тогда, очевидно, вы вставляете строки, нарушающие это правило (например, дату в 2016 году) - person a_horse_with_no_name; 12.10.2016
comment
Вы имеете в виду, что уже есть некоторые существующие записи, нарушающие это правило? - person Sean Li; 13.10.2016

у вас есть дата изготовления

ALTER TABLE SIGHTINGS 
   ADD CONSTRAINT CK_SIGHTING_DATE 
   CHECK (SIGHTING_DATE <= 
               /*TO_DATE('01-JAN-16','DD-MON-YY') as I was pointed your should specify 4 digits for year*/ 
                 TO_DATE('01-JAN-2016','DD-MON-YYYY'));

or

 ALTER TABLE SIGHTINGS 
   ADD CONSTRAINT CK_SIGHTING_DATE 
   CHECK (SIGHTING_DATE <=DATE'2016-01-01');

еще одна вещь, что вы имеете в виду, когда говорите «не более 2016 года». Ваш чек позволяет датировать 01 января 2016 года, но не разрешает 02 января 2016 года. Если вы хотите включить весь 2016 год, напишите

SIGHTING_DATE < DATE'2017-01-01'

или trunc(SIGHTING_DATE,'yy') ‹=DATE'2016-01-01'

person Michael Piankov    schedule 11.10.2016
comment
'01-JAN-16','DD-MON-YY' зависит от локального NLS_DATE_LANGUAGE, это может привести к сбою для других языков, кроме английского. Также год с двумя цифрами 16 не очень умный. - person Wernfried Domscheit; 11.10.2016
comment
Как это зависит? Я пишу строку символов и указываю формат. За весь век с 2000 по 2099 год он будет возвращать дату 01 января 2016 года. - person Michael Piankov; 11.10.2016
comment
Когда я пробую ваше первое предложение, я получаю ту же ошибку: ORA-02436: дата или системная переменная неправильно указаны в ограничении CHECK - person Wernfried Domscheit; 11.10.2016