Oracle
 sql >> база данни >  >> RDS >> Oracle

Изваждане на дати в Oracle - числови или интервални тип данни?

Добре, обикновено не отговарям на собствените си въпроси, но след малко бърникане разбрах окончателно как Oracle съхранява резултата от изваждане на ДАТА.

Когато извадите 2 дати, стойността не е тип данни NUMBER (както би ви накарало да повярвате в справочното ръководство на Oracle 11.2 SQL). Номерът на вътрешния тип данни на изваждане DATE е 14, което е недокументиран вътрешен тип данни (NUMBER е вътрешен тип данни номер 2). Въпреки това, той всъщност се съхранява като 2 отделни допълващи се числа със знак от две, като първите 4 байта се използват за представяне на броя дни, а последните 4 байта, използвани за представяне на броя на секундите.

Пример за изваждане на DATE, което води до положителна разлика в цяло число:

select date '2009-08-07' - date '2008-08-08' from dual;

Резултати в:

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

Припомнете си, че резултатът е представен като 2 отделни две допълнения със знак от 4 байтови числа. Тъй като в този случай няма десетични знаци (точно 364 дни и 0 часа), последните 4 байта са 0 и могат да бъдат игнорирани. За първите 4 байта, тъй като моят процесор има архитектура с малък ендиан, байтовете са обърнати и трябва да се четат като 1108 или 0x16c, което е десетично 364.

Пример за изваждане на DATE, което води до отрицателна целочислена разлика:

select date '1000-08-07' - date '2008-08-08' from dual;

Резултати в:

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

Отново, тъй като използвам машина с малък ендиан, байтовете са обърнати и трябва да се четат като 255,250,97,224, което съответства на 11111111 11111010 01100001 11011111. Сега, тъй като това е в допълнение към две, знаем, че числото enco bin е със знак отрицателно, защото най-лявата двоична цифра е 1. За да преобразуваме това в десетично число, ще трябва да обърнем допълнението на 2 (изваждаме 1 и след това правим допълнението на единицата), което води до:00000000 00000101 10011110 00100006810, което е равно. P>

Пример за изваждане на DATE, което води до десетична разлика:

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

Разликата между тези 2 дати е 0,25 дни или 6 часа.

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

Сега този път, тъй като разликата е 0 дни и 6 часа, се очаква първите 4 байта да са 0. За последните 4 байта можем да ги обърнем (тъй като CPU е с малък байт) и да получим 84,96 =01010100 01100000 основа 2 =21600 в десетичната запетая. Преобразуването на 21600 секунди в часове ви дава 6 часа, което е разликата, която очаквахме.

Надявам се това да помогне на всеки, който се чудеше как всъщност се съхранява изваждане на ДАТА.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да създадете PL/SQL SYS_REFCURSOR в база данни на Oracle

  2. Друга бяла книга за 12c Optimizer

  3. Как да боравим с незадължителни параметри в SQL заявка?

  4. Пресъздайте лош RAC възел

  5. Синтактичен анализ на имена на таблици и колони от SQL/HQL Java