我不明白这个Oracle约束:
ALTER TABLE TableName ADD (
CONSTRAINT CHK_DATE
CHECK (date_start = trunc(date_start, 'dd') and date_end = trunc(date_end, 'dd')));
它总是抛出ORA-02290错误。 有人可以帮我解释一下。
答案 0 :(得分:4)
它会检查date_start
和date_end
的时间值是否为00:00:00
(i-e no time component)。
Oracle中的DATE
数据类型是一个时间点(精确到秒)。因此它总是有一个时间组件。
对于许多应用程序,有时使用没有时间组件的整天是有用的,因为整天计算更容易。因此,为了确保插入的所有日期都没有时间组件,您可以向列添加约束。
要插入或更新,请使用没有时间的格式(或时间= 00:00:00):
to_date('2013-01-01', 'yyyy-mm-dd')
或使用TRUNC
。
答案 1 :(得分: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)
分享并享受。
答案 2 :(得分: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