Oracle stocke DATE
s dans des tableaux utilisant 7 octets où les 2 premiers octets sont :
- Siècle + 100
- Année du siècle + 100
Ainsi, la date maximale qui peut (techniquement) être stockée est lorsque ces deux octets ont les valeurs 255
et 199
ce qui donnerait une année de 15599
(J'ignore que vous pourriez théoriquement stocker 255
dans le deuxième octet car cela ouvre tout un tas de problèmes distincts).
Vous pouvez convertir une valeur brute en une date en utilisant le DBMS_STATS.CONVERT_RAW_VALUE
ce qui signifie que nous pouvons contourner les méthodes normales de création de dates et générer directement les valeurs d'octets qui seront stockées.
Cette fonction en est un exemple :
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;
/
Ensuite, si vous avez une colonne de date, vous pouvez insérer des valeurs que vous n'êtes normalement pas autorisé à insérer :
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
ne fonctionne pas lorsque l'année dépasse les limites normales d'une date. Pour obtenir les valeurs stockées dans la table, vous pouvez utiliser DUMP
pour obtenir une chaîne contenant les valeurs d'octets ou vous pouvez utiliser EXTRACT
pour obtenir les composants individuels.
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;
sorties :
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<>jouez ici