Ok, normalnie nie odpowiadam na własne pytania, ale po odrobinie majsterkowania, ustaliłem definitywnie, w jaki sposób Oracle przechowuje wynik odejmowania DATE.
Po odjęciu 2 dat, wartość nie jest typem danych LICZBY (tak, jak uważasz, że Oracle 11.2 SQL Reference manual). Wewnętrzny numer typu danych odejmowania DATE to 14, który jest nieudokumentowanym wewnętrznym typem danych (NUMBER to internal datatype number 2). Jest on jednak przechowywany jako 2 oddzielne podpisane dopełnienia dwóch uzupełnień, przy czym pierwsze 4 bajty służą do reprezentowania liczby dni i ostatnich 4 bajtów używanych do reprezentowania liczby sekund.
Przykład odejmowania DATE, w wyniku dodatniej różnicy całkowitej:
select date '2009-08-07' - date '2008-08-08' from dual;
Wyniki w:
DATE'2009-08-07'-DATE'2008-08-08'
---------------------------------
364
select dump(date '2009-08-07' - date '2008-08-08') from dual;
DUMP(DATE'2009-08-07'-DATE'2008
-------------------------------
Typ=14 Len=8: 108,1,0,0,0,0,0,0
Przypomnijmy, że wynik jest przedstawiony jako 2 oddzielne uzupełnienie dwójkowe podpisany 4 liczby bajtów . Ponieważ w tym przypadku nie ma liczb dziesiętnych (dokładnie 364 dni i 0 godzin), ostatnie 4 bajty są zerami i można je zignorować. W przypadku pierwszych 4 bajtów, ponieważ mój procesor ma architekturę typu little-endian, bajty są odwrócone i powinny być odczytywane jako 1,108 lub 0x16c, który jest dziesiętny 364.
Przykład odejmowania DATE, co daje ujemną różnicę całkowitą :
select date '1000-08-07' - date '2008-08-08' from dual;
Wyniki w:
DATE'1000-08-07'-DATE'2008-08-08'
---------------------------------
-368160
select dump(date '1000-08-07' - date '2008-08-08') from dual;
DUMP(DATE'1000-08-07'-DATE'2008-08-0
------------------------------------
Typ=14 Len=8: 224,97,250,255,0,0,0,0
Ponownie, ponieważ używam mało endian maszynę, bajty są odwracane i powinny być odczytywane jako 255,250,97,224 która odpowiada 11111111 11111010 01100001 11011111. Teraz, ponieważ jest to dopełnienie dwójki podpisane kodowanie liczb binarnych, wiemy, że liczba jest ujemna, ponieważ najdalsza od lewej cyfra binarna to 1. Aby przekonwertować to na liczbę dziesiętną, musielibyśmy odwrócić dopełnienie 2 (odjąć 1, a następnie uzupełnić), uzyskując: 00000000 00000101 10011110 00100000, co odpowiada -368160 jako podejrzane.
Przykład odejmowania DATE, w wyniku różnicy dziesiętnych:
select to_date('08/AUG/2004 14:00:00', 'DD/MON/YYYY HH24:MI:SS'
- to_date('08/AUG/2004 8:00:00', 'DD/MON/YYYY HH24:MI:SS') from dual;
TO_DATE('08/AUG/200414:00:00','DD/MON/YYYYHH24:MI:SS')-TO_DATE('08/AUG/20048:00:
--------------------------------------------------------------------------------
.25
Różnica między tymi 2 dniach jest 0,25 dzień lub około 6 godzin.
select dump(to_date('08/AUG/2004 14:00:00', 'DD/MON/YYYY HH24:MI:SS')
- to_date('08/AUG/2004 8:00:00', 'DD/MON/YYYY HH24:MI:SS')) from dual;
DUMP(TO_DATE('08/AUG/200414:00:
-------------------------------
Typ=14 Len=8: 0,0,0,0,96,84,0,0
Teraz ten czas, ponieważ różnica wynosi 0 dni i 6 godzin, oczekuje się, że pierwsze 4 bajty są 0. Przez ostatnie 4 bajty, możemy je odwrócić (bo procesor jest little-endian) i uzyskaj 84,96 = 01010100 01100000 podstawa 2 = 21600 w systemie dziesiętnym. Konwersja 21600 sekund na godziny daje 6 godzin, co jest różnicą, której się spodziewaliśmy.
Mam nadzieję, że pomoże to każdemu, kto zastanawia się, jak faktycznie odejmowanie DATE jest rzeczywiście przechowywane.
Czy zdarza się to kiedy można umieścić zamiast sysdate coś jak TO_DATE (' 20120216' , 'rrrrmmdd')? –
Cześć przepraszam, nie widziałem twojego komentarza do tej pory: S .. Po pierwsze, aby odpowiedzieć na twoje pytanie, tak, robi to nawet jeśli używa "to_date()" zamiast SYSDATE. Z drugiej strony udało mi się dowiedzieć, jak zapisuje się odejmowanie DATE, więc napisałem to jako moją odpowiedź: D .. ponieważ nikt inny w Internecie nie napisał o tym jeszcze, pomyślałem, że napiszę co ja dowiedziałem się. – BYS2
@ BYS2 - Po co wstawiać liczbę(), a następnie spróbować odjąć dni od liczby i przekonwertować ją na sekundy: WYBIERZ (1242.12423) DZIEŃ (5) DO DRUGIEGO od testu? Oto, o co musisz zapytać. – Art