2013-06-27 2 views
0

Я не понимаю, это Oracle ограничения:Что проверяет это Oracle ограничение

ALTER TABLE TableName ADD (
CONSTRAINT CHK_DATE 
CHECK (date_start = trunc(date_start, 'dd') and date_end = trunc(date_end, 'dd'))); 

Он всегда выдает ошибку ORA-02290. Может кто-нибудь объяснить это мне, пожалуйста.

+2

Из того, что я могу сказать, что это ограничение подтверждает, что DATE_START и date_end не имеют каких-либо компонентов времени в них. Таким образом, действительны только даты, которые имеют 00:00:00 в течение часов, минут и секунд. – mtwaddell

ответ

4

Он проверяет, что и date_start, и date_end имеют значение времени 00:00:00 (i-e не время).

Тип данных DATE в Oracle - это момент времени (точный для второго). Таким образом, он всегда имеет компонент времени.

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

Для вставки или обновления, использовать либо формат без времени (или со временем = 00: 00: 00):

to_date('2013-01-01', 'yyyy-mm-dd') 

или использовать TRUNC.

1

Это ограничение указывает, что оба поля DATE_START и DATE_END должны быть усеченными датами, то есть не должны указываться в течение нескольких часов, минут и секунд. Таким образом, следующий INSERT должен работать:

INSERT INTO TABLENAME (DATE_START, DATE_END) 
    VALUES (TRUNC(SYSDATE), TRUNC(SYSDATE)+INTERVAL '1' DAY) 

, а следующий не будет:

INSERT INTO TABLENAME (DATE_START, DATE_END) 
    VALUES (SYSDATE, SYSDATE+INTERVAL '1' DAY) 

Делите и наслаждайтесь.

1

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

Ваше ограничение просто гарантирует, что столбцы даты + времени date_start и date_end ценности соответствуют ожиданиям и не сохраняют какой-либо компонент времени.

Пример:

SELECT t, CASE WHEN t=trunc(t,'DD') THEN 'check ok' ELSE 'check fails' END AS chk 
    FROM (select (DATE '2013-06-26' - INTERVAL '1' HOUR)+10*level*(1/24/60) as t from dual connect by level < 12); 

25.06.2013 23:10:00 check fails 
25.06.2013 23:20:00 check fails 
25.06.2013 23:30:00 check fails 
25.06.2013 23:40:00 check fails 
25.06.2013 23:50:00 check fails 
26.06.2013 00:00:00 check ok 
26.06.2013 00:10:00 check fails 
26.06.2013 00:20:00 check fails 
26.06.2013 00:30:00 check fails 
26.06.2013 00:40:00 check fails 
26.06.2013 00:50:00 check fails