Table my_table is:
CREATE TABLE MY_TABLE(
ID NUMBER NOT NULL,
MY_DATE DATE NOT NULL);
Typing the following query:
select sysdate from dual
the result is:
10-MAG-12 21:22:32
note that mag = may.
Now, if I type this query:
select *
from my_table
where my_date <= sysdate
the result is:
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
Note that in my_table I have only these 4 records. Why I see all the records and not the first and second record only? Thanks.
I use Oracle SQL Developer.
Edit: please note that when I insert a record with PL/SQL I type something like:
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;
I suspect that the data being stored in your table does not have a year of 2012. It probably has a year of 0012 (two thousand years ago).
What do you see when you run the query
I expect that the year will be 0012 rather than 2012. The reason for that is that the code you’re using to insert the data is incorrectly converting a date to a string without using an explicit format mask then converts the string back to a date using an explicit format mask that happens not to match the session’s
NLS_DATE_FORMAT. In general, if you ever find yourself converting a date to a string and back to a date, you’re probably doing something wrong. If you change your code to simply do date manipulation, it will be more efficient, more robust, and less error-prone.Walking through why the original code goes wrong
This takes
SYSDATEand truncates it to midnight on the current day. So far, so good. Then, it callsTO_CHARwithout an explicit format mask. This causes Oracle to use the session’sNLS_DATE_FORMAT, meaning that different users with different settings will get different results. If your session’sNLS_DATE_FORMAThappens to be ‘dd-mon-rr hh24:mi:ss’, which I’m guessing based on the query results you posted, that will mean that the string has a 2-digit year. YourSUBSTRappears to assume that the output has just a two-digit year (if you have a differentNLS_DATE_FORMAT, yourSUBSTRwill generate different bugs such as potentially cutting off the 12 from a year of 2012 leaving a year of just 20).Assuming
stringDateis something like10-MAG-12, this next line generates a string10-MAG-12 20:00:00and then tries to convert it to a date using the format maskdd-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.