Oracle speichert DATE
s in Tabellen mit 7 Bytes, wobei die ersten 2 Bytes sind:
- Jahrhundert + 100
- Jahrhundert + 100
Das maximale Datum, das (technisch) gespeichert werden kann, ist also, wenn diese beiden Bytes die Werte 255
haben und 199
was das Jahr 15599
ergeben würde (Ich ignoriere, dass Sie theoretisch 255
speichern könnten im zweiten Byte, da dies einen ganzen Haufen separater Probleme aufwirft).
Sie können einen Rohwert mithilfe von DBMS_STATS.CONVERT_RAW_VALUE
in ein Datum umwandeln Das bedeutet, dass wir die normalen Methoden zum Erstellen von Daten umgehen und die zu speichernden Bytewerte direkt generieren können.
Diese Funktion ist ein Beispiel dafür:
CREATE FUNCTION createDate(
year int,
month int,
day int,
hour int,
minute int,
second int
) RETURN DATE DETERMINISTIC
IS
hex CHAR(14);
d DATE;
BEGIN
hex := TO_CHAR( FLOOR( year / 100 ) + 100, 'fm0X' )
|| TO_CHAR( MOD( year, 100 ) + 100, 'fm0X' )
|| TO_CHAR( month, 'fm0X' )
|| TO_CHAR( day, 'fm0X' )
|| TO_CHAR( hour + 1, 'fm0X' )
|| TO_CHAR( minute + 1, 'fm0X' )
|| TO_CHAR( second + 1, 'fm0X' );
DBMS_OUTPUT.PUT_LINE( hex );
DBMS_STATS.CONVERT_RAW_VALUE( HEXTORAW( hex ), d );
RETURN d;
END;
/
Wenn Sie dann eine Datumsspalte haben, können Sie Werte einfügen, die Sie normalerweise nicht einfügen dürfen:
CREATE TABLE table_name ( date_column DATE );
INSERT INTO table_name ( date_column )
VALUES ( DATE '2019-12-31' + INTERVAL '1:02:03' HOUR TO SECOND );
INSERT INTO table_name ( date_column ) VALUES ( createDate( 15599, 12, 31, 1, 2, 3 ) );
INSERT INTO table_name ( date_column ) VALUES ( createDate( 12017, 2, 21, 0, 0, 0 ) );
TO_CHAR
funktioniert nicht, wenn das Jahr die normalen Grenzen eines Datums überschreitet. Um die in der Tabelle gespeicherten Werte zu erhalten, können Sie DUMP
verwenden um einen String zu erhalten, der die Bytewerte enthält, oder Sie können EXTRACT
verwenden um die einzelnen Komponenten zu erhalten.
SELECT DUMP( date_column ),
TO_CHAR( date_column, 'YYYY-MM-DD' ) AS value,
TO_CHAR( EXTRACT( YEAR FROM date_column ), 'fm00000' )
|| '-' || TO_CHAR( EXTRACT( MONTH FROM date_column ), 'fm00' )
|| '-' || TO_CHAR( EXTRACT( DAY FROM date_column ), 'fm00' )
|| ' ' || TO_CHAR( EXTRACT( HOUR FROM CAST( date_column AS TIMESTAMP ) ), 'fm00' )
|| ':' || TO_CHAR( EXTRACT( MINUTE FROM CAST( date_column AS TIMESTAMP ) ), 'fm00' )
|| ':' || TO_CHAR( EXTRACT( SECOND FROM CAST( date_column AS TIMESTAMP ) ), 'fm00' )
AS full_value
FROM table_name;
Ausgaben:
DUMP(DATE_COLUMN) | VALUE | FULL_VALUE :-------------------------------- | :--------- | :------------------- Typ=12 Len=7: 120,119,12,31,2,3,4 | 2019-12-31 | 02019-12-31 01:02:03 Typ=12 Len=7: 255,199,12,31,2,3,4 | 0000-00-00 | 15599-12-31 01:02:03 Typ=12 Len=7: 220,117,2,21,1,1,1 | 0000-00-00 | 12017-02-21 00:00:00
db<>hier fummeln