Oracle menyimpan DATE
s dalam tabel menggunakan 7 byte di mana 2 byte pertama adalah:
- Abad + 100
- Tahun abad + 100
Jadi tanggal maksimum yang dapat (secara teknis) disimpan adalah ketika kedua byte tersebut memiliki nilai 255
dan 199
yang akan memberikan tahun 15599
(Saya mengabaikan bahwa Anda secara teoritis dapat menyimpan 255
di byte kedua karena itu membuka banyak masalah terpisah).
Anda dapat mengonversi nilai mentah menjadi tanggal menggunakan DBMS_STATS.CONVERT_RAW_VALUE
yang berarti kita dapat melewati metode normal untuk membuat tanggal dan secara langsung menghasilkan nilai byte yang akan disimpan.
Fungsi ini adalah contohnya:
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;
/
Kemudian jika Anda memiliki kolom tanggal, Anda dapat memasukkan nilai yang biasanya tidak boleh Anda masukkan:
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
tidak bekerja ketika tahun melebihi batas normal tanggal. Untuk mendapatkan nilai yang disimpan dalam tabel, Anda dapat menggunakan DUMP
untuk mendapatkan string yang berisi nilai byte atau Anda dapat menggunakan EXTRACT
untuk mendapatkan komponen individual.
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;
keluaran:
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<>main biola di sini