2013-11-23 62 views
0

EMPLOYEE表:使用比甲骨文少比较日期不能得到预期的答案

CREATE TABLE Employee(
    ID CHAR(10) PRIMARY KEY, 
    SSN CHAR(15) NOT NULL, 
    FNAME CHAR(15), 
    LNAME CHAR(15), 
    DOB DATE NOT NULL 
); 
INSERT INTO Employee VALUES('0000000001','078-05-1120','George','Brooks', '24-may-85'); 
INSERT INTO Employee VALUES('0000000002','917-34-6302','David','Adams', '01-apr-63'); 
INSERT INTO Employee VALUES('0000000003','078-05-1123','Yiling','Zhang', '02-feb-66'); 
INSERT INTO Employee VALUES('0000000004','078-05-1130','David','Gajos', '10-feb-65'); 
INSERT INTO Employee VALUES('0000000005','079-04-1120','Steven','Cox', '11-feb-79'); 
INSERT INTO Employee VALUES('0000000006','378-35-1108','Eddie','Gortler', '30-may-76'); 
INSERT INTO Employee VALUES('0000000007','278-05-1120','Henry','Kung', '22-may-81'); 
INSERT INTO Employee VALUES('0000000008','348-75-1450','Harry','Leitner', '29-oct-85'); 
INSERT INTO Employee VALUES('0000000009','256-90-4576','David','Malan', '14-oct-88'); 
INSERT INTO Employee VALUES('0000000010','025-45-1111','John','Brooks', '28-nov-78'); 
INSERT INTO Employee VALUES('0000000011','025-59-1919','Michael','Morrisett', '04-nov-85'); 
INSERT INTO Employee VALUES('0000000012','567-45-2351','David','Nelson', '10-nov-54'); 
INSERT INTO Employee VALUES('0000000013','100-40-0011','Jelani','Parkes', '20-dec-44'); 

当我使用类似的查询:

SELECT * FROM EMPLOYEE WHERE DOB < '01-jan-80'; 

我没有得到的“0000000013”的记录, '100-40-0011','Jelani','Parkes','20 -dec-44'。 我认为这可能是日期格式问题,但我不确定。任何人有想法?谢谢!

回答

2

您提供一年

然后一年< 50将20XX 和年> 50将19XX

意味着56将:

试试这个1956年是44 意味着2044

这就是为什么它被排除

3

那么,你有一个DATE数据类型为你的DOB列,所以,这是一件好事。但是,使用字符串指定日期时,应该使用明确的TO_DATE函数和4位数年来确切确定发生了什么。在2位格式(RR)

INSERT INTO Employee VALUES('0000000001','078-05-1120','George','Brooks', to_date('24-may-1985','dd-mon-yyyy')); 
INSERT INTO Employee VALUES('0000000002','917-34-6302','David','Adams', to_date('01-apr-1963','dd-mon-yyyy')); 
INSERT INTO Employee VALUES('0000000003','078-05-1123','Yiling','Zhang', to_date('02-feb-1966','dd-mon-yyyy')); 
INSERT INTO Employee VALUES('0000000004','078-05-1130','David','Gajos', to_date('10-feb-1965','dd-mon-yyyy')); 
INSERT INTO Employee VALUES('0000000005','079-04-1120','Steven','Cox', to_date('11-feb-1979','dd-mon-yyyy')); 
INSERT INTO Employee VALUES('0000000006','378-35-1108','Eddie','Gortler', to_date('30-may-1976','dd-mon-yyyy')); 
INSERT INTO Employee VALUES('0000000007','278-05-1120','Henry','Kung', to_date('22-may-1981','dd-mon-yyyy')); 
INSERT INTO Employee VALUES('0000000008','348-75-1450','Harry','Leitner', to_date('29-oct-1985','dd-mon-yyyy')); 
INSERT INTO Employee VALUES('0000000009','256-90-4576','David','Malan', to_date('14-oct-1988','dd-mon-yyyy')); 
INSERT INTO Employee VALUES('0000000010','025-45-1111','John','Brooks', to_date('28-nov-1978','dd-mon-yyyy')); 
INSERT INTO Employee VALUES('0000000011','025-59-1919','Michael','Morrisett', to_date('04-nov-1985','dd-mon-yyyy')); 
INSERT INTO Employee VALUES('0000000012','567-45-2351','David','Nelson', to_date('10-nov-1954','dd-mon-yyyy')); 
INSERT INTO Employee VALUES('0000000013','100-40-0011','Jelani','Parkes', to_date('20-dec-1944','dd-mon-yyyy')); 

SELECT * FROM EMPLOYEE WHERE DOB < to_date('01-jan-1980','dd-mon-yyyy'); 
1

您的插入语句的日期没有指定掩码。这意味着它将使用默认日期掩码。你可以用下面的查询来检查它的值:

select * from NLS_DATABASE_PARAMETERS 
where parameter = 'NLS_DATE_FORMAT'; 

年份是两位数字格式;这意味着Oracle必须默认一个世纪。如果适用的掩码是YY它将选择当前世纪; 44将变为2044,80将变成2080.

但是,看起来您可能有一个使用RR格式的掩码,例如,DD-MON-RR。这适用于一个钝的窗口来推导出一个世纪的缺乏一个的输入日期,以50为旋转数。小于50的数字得到当前世纪,否则它们将得到前一个世纪。所以80年将成为1950年,44年将成为2044年。显然,2044年不低于1980年。

如果您的数据库使用RR作为其默认日期掩码,这是非常糟糕的做法。 RR格式是在上个千年的Y2K歇斯底里期间作为紧急杂志引入的。没有现代系统应该仍然使用它。所有输入应包含适当的完整日期和格式掩码。

继续依赖RR格式的系统将越来越多地被损坏。随着21世纪的进展,RR窗口的关键点变得不太合适。没有办法改变枢轴点,因为它只是作为一个混乱。

最初的Y2K问题起源于一个真正的存储问题:省略世纪数字节省了大量的空间。早在20世纪80年代就是这样。空间对于十年(除了某些专业环境(例如嵌入式系统))没有那么大的问题。现代系统应该总是妥善处理世纪;不这样做只是懒惰或无知。