0

我不明白这个 Oracle 约束:

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

它总是抛出 ORA-02290 错误。有人可以为我解释一下吗?

4

3 回答 3

4

它检查两者date_startdate_end时间值00:00:00(即没有时间分量)。

Oracle 中的DATE数据类型是一个时间点(精确到秒)。因此它总是有一个时间分量。

对于许多应用程序,有时使用不带时间组件的全天很有用,因为使用全天计算更容易。因此,要确保所有插入的日期都没有时间组件,您可以向列添加约束。

要插入或更新,请使用不带时间的格式(或使用时间=00:00:00):

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

或使用TRUNC.

于 2013-06-27T13:33:05.477 回答
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)

分享和享受。

于 2013-06-27T13:36:52.113 回答
1

Oracle 无法提供没有任何时间来存储日期值的方法。您可以将时间部分始终保持在午夜,很多用户都会这样做。但是,如果不知何故有几分钟或几小时潜入该列,日期算术可能会失败,可能没有任何人注意到。

您的约束只是确保日期+时间列date_startdate_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
于 2013-06-27T13:40:50.873 回答