2013-06-27 88 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_startdate_end的时间值为00:00:00(即没有时间分量)。

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

对于许多应用程序而言,使用整天没有时间组件有时会很有用,因为整天的计算都比较容易。因此,为了确保插入的所有日期都没有时间分量,可以向该列添加约束。

要插入或更新,使用的格式,而不时间(或者具有时间= 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_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