1

表 my_table 是:

CREATE TABLE MY_TABLE(
ID        NUMBER  NOT NULL,
MY_DATE   DATE    NOT NULL);

键入以下查询:

select sysdate from dual

结果是:

10-MAG-12 21:22:32

请注意,mag = may。

现在,如果我输入这个查询:

select *
from my_table
where my_date <= sysdate

结果是:

9918    10-MAG-12 20:00:00
9915    10-MAG-12 21:00:00
9952    10-MAG-12 22:00:00
9951    10-MAG-12 23:00:00

请注意,在 my_table 我只有这 4 条记录。为什么我看到所有记录而不是第一条和第二条记录?谢谢。

我使用 Oracle SQL Developer。

编辑:请注意,当我使用 PL/SQL 插入记录时,我输入如下内容:

nCount NUMBER;
myDate DATE;
stringDate VARCHAR2(255);
BEGIN
nCount := 0;
stringDate := substr(to_char(trunc(sysdate)),0,9);
myDate := to_date(stringDate || ' 20:00:00','dd-mm-yyyy hh24:mi:ss');
for t in (a cursor) loop
   insert into MY_TABLE(ID,MY_DATE)
   values (9918,myDate+(nCount/1440));
   nCount := nCount + 60;
end loop;
END;
4

1 回答 1

3

我怀疑存储在表中的数据没有 2012 年。它可能有 0012 年(两千年前)。

运行查询时会看到什么

SELECT id, to_char( my_date, 'dd-mm-yyyy hh24:mi:ss' )
  FROM my_table

我预计年份将是 0012 而不是 2012。原因是您用于插入数据的代码在不使用显式格式掩码的情况下错误地将日期转换为字符串,然后将字符串转换回日期使用恰好与会话不匹配的显式格式掩码NLS_DATE_FORMAT。一般来说,如果您发现自己将日期转换为字符串并返回日期,那么您可能做错了什么。如果您将代码更改为简单地进行日期操作,它将更高效、更健壮且不易出错。

DECLARE
  nCount NUMBER;
  myDate DATE;
BEGIN
  nCount := 0;
  myDate := trunc(sysdate) + interval '20' hour;
  for t in (a cursor) loop
     insert into MY_TABLE(ID,MY_DATE)
       values (9918,myDate+(nCount/1440));
     nCount := nCount + 60;
  end loop;
END;

了解原始代码出错的原因

stringDate := substr(to_char(trunc(sysdate)),0,9);

SYSDATE会将其截断到当天的午夜。到现在为止还挺好。TO_CHAR然后,它在没有显式格式掩码的情况下调用。这会导致 Oracle 使用会话的NLS_DATE_FORMAT,这意味着具有不同设置的不同用户将获得不同的结果。如果您的会话NLS_DATE_FORMAT恰好是“dd-mon-rr hh24:mi:ss”,我根据您发布的查询结果猜测,这将意味着该字符串有一个两位数的年份。您SUBSTR似乎假设输出只有两位数的年份(如果您有不同的年份NLS_DATE_FORMAT,您SUBSTR将产生不同的错误,例如可能会从 2012 年的一年中删除 12 年,留下只有 20 年的年份)。

myDate := to_date(stringDate || ' 20:00:00','dd-mm-yyyy hh24:mi:ss');

Assuming stringDate is something like 10-MAG-12, this next line generates a string 10-MAG-12 20:00:00 and then tries to convert it to a date using the format mask dd-mm-yyyy hh24:mi:ss. This assumes that the string has a 4-digit year so when it only finds 2-digits, it assumes that you meant the year 12, not the year 2012.

于 2012-05-10T17:25:51.647 回答