Subtrahieren von Daten in Oracle - Number oder Interval Datatype?
Ich habe eine Frage über einige der internen Abläufe für die Oracle-DATUM und INTERVALL-Datentypen. Nach der Oracle 11.2 SQL-Referenzwenn Sie subtrahieren 2 DATUM datatypes, wird das Ergebnis ein ZAHL-Datentyp.
Auf oberflächliche Prüfung, dies scheint wahr zu sein:
CREATE TABLE test (start_date DATE);
INSERT INTO test (start_date) VALUES (date'2004-08-08');
SELECT (SYSDATE - start_date) from test;
wird eine ZAHL zurückgeben Datentyp.
Aber jetzt, wenn Sie tun:
SELECT (SYSDATE - start_date) DAY(5) TO SECOND from test;
erhalten Sie eine INTERVAL-Datentyp. In anderen Worten, Oracle können, konvertieren Sie die ZAHL aus dem DATUM Subtraktion in einem INTERVALL geben.
So, jetzt dachte ich, ich könnte versuchen Sie in ein ZAHL-Datentyp, der direkt in die Klammern (anstatt das zu tun 'DATEPART - start_date', die Ergebnisse in eine REIHE sowieso):
SELECT (1242.12423) DAY(5) TO SECOND from test;
Aber diese Ergebnisse in der Fehlermeldung:
ORA-30083: syntax error was found in interval value expression
Also meine Frage ist: was ist hier Los? Es scheint, wie die Subtraktion von Datumsangaben sollten führen zu einer REIHE (wie gezeigt in der SELECT-Anweisung #1), die NICHT automatisch umgewandelt, INTERVALL-Typ (wie gezeigt in der SELECT-Anweisung #3). Aber Oracle scheint in der Lage zu tun, irgendwie, wenn Sie das DATUM der Subtraktion Ausdruck anstatt in eine raw-REIHE (SELECT-Anweisung #2).
Dank
InformationsquelleAutor der Frage BYS2 | 2012-02-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ok, ich normalerweise nicht Antwort auf meine eigenen Fragen, aber nach ein wenig basteln habe ich herausgefunden, endgültig, wie Oracle speichert das Ergebnis der DATE-Subtraktion.
Beim subtrahieren 2 Termine, der Wert ist nicht ein ZAHL-Datentyp (wie die Oracle 11.2 SQL-Referenzhandbuch würden Sie glauben). Der interne Datentyp Zahl für ein DATUM Subtraktion ist 14, die eine nicht-dokumentierte interne Datentyp (ZAHL interne Datentyp Zahl 2). Allerdings ist es tatsächlich so gespeichert, wie Sie 2 separate zwei-Komplement-zahlen unterzeichnet, mit den ersten 4 Byte repräsentieren die Anzahl der Tage und die letzten 4 bytes verwendet und repräsentiert die Anzahl der Sekunden.
Ein Beispiel für ein DATUM, Subtraktion, wodurch eine positive ganze Zahl Unterschied:
Ergebnisse in:
Daran erinnern, dass das Ergebnis dargestellt wird als 2 separate Zweierkomplement signed 4-byte-zahlen. Da es keine Nachkommastellen in diesem Fall (364 Tage und 0 Stunden genau), die letzten 4 bytes sind alle 0 und kann ignoriert werden. Für die ersten 4 bytes, weil meine CPU hat eine little-endian-Architektur, die bytes vertauscht sind und sollte gelesen werden als 1,108 oder 0x16c, die dezimal 364.
Ein Beispiel für ein DATUM, Subtraktion, wodurch eine negative Ganzzahl Unterschied:
Ergebnisse in:
Wieder, da bin ich mit einer little-endian Maschine, werden die bytes vertauscht sind und sollte gelesen werden als 255,250,97,224 das entspricht 11111111 11111010 01100001 11011111. Nun seit heute ist im Zweierkomplement unterzeichnet, binäre Ziffern-Codierung, wissen wir, dass die Zahl negativ ist, weil die Links binäre Ziffer ist eine 1. Konvertieren diese in eine dezimale Zahl, die wir hätten umkehren der 2-Komplement (subtrahieren Sie 1, dann tun Sie das Einerkomplement) ergibt: 00000000 00000101 10011110 00100000 entspricht -368160 als vermutet.
Ein Beispiel für ein DATUM Subtraktion resultierende in eine Dezimalzahl Unterschied:
Den Unterschied zwischen den 2 Terminen ist 0,25 Tage oder 6 Stunden.
Nun ist diese Zeit, da der Unterschied ist 0 Tage und 6 Stunden, es wird erwartet, dass die ersten 4 bytes sind 0. Für die letzten 4 bytes können wir Umgekehrt (weil die CPU little-endian) und bekommen 84,96 = 01010100 01100000 Basis 2 = 21600 in dezimal. Konvertieren von 21600 Sekunden zu Stunden haben Sie 6 Stunden, das ist der Unterschied, welchen wir erwartet haben.
Hoffe, dies hilft jemand, der sich fragte, wie ein DATUM Subtraktion gespeichert.
InformationsquelleAutor der Antwort BYS2
Erhalten Sie die syntax-Fehler, da das Datum der Mathematik nicht wieder eine ZAHL, aber es gibt ein INTERVALL:
Müssen Sie zum konvertieren der Zahl in deinem Beispiel in einem INTERVALL zuerst mit der NUMTODSINTERVAL Funktion
Beispiel:
Basierend auf der reverse-cast mit der NUMTODSINTERVAL () - Funktion, es scheint einige Rundung ist in der übersetzung verloren.
InformationsquelleAutor der Antwort tawman
Ein paar Punkte:
Subtraktion eines Datums von einem anderen Ergebnis in eine Zahl; Subtraktion einen timestamp aus aus einem anderen Ergebnisse in einem Intervall.
Oracle konvertiert Zeitstempel, Datumsangaben intern bei der Durchführung timestamp rechnen.
Intervall-Konstanten können nicht verwendet werden, in der entweder das Datum oder timestamp-Arithmetik.
Oracle 11gR2 SQL-Referenz Datetime-Matrix
InformationsquelleAutor der Antwort Michael Milligan
select TIMEDIFF (STR_TO_DATE('07:15 Uhr', '%h:%i %p') , STR_TO_DATE('9:58 AM', '%h:%i %p'))
InformationsquelleAutor der Antwort Pankaj Pathak