Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Oracle 10g akceptuje 5-cyfrowy rok w Dacie

Oracle przechowuje DATE s w tabelach przy użyciu 7 bajtów, gdzie pierwsze 2 bajty to:

  • Wiek + 100
  • Rok stulecia + 100

Tak więc maksymalna data, która może (technicznie) być przechowywana, jest wtedy, gdy te dwa bajty mają wartości 255 i 199 co dałoby rok 15599 (ignoruję, że teoretycznie można by przechowywać 255 w drugim bajcie, ponieważ otwiera to całą stertę oddzielnych problemów).

Możesz przekonwertować nieprzetworzoną wartość na datę za pomocą DBMS_STATS.CONVERT_RAW_VALUE co oznacza, że ​​możemy ominąć normalne metody tworzenia dat i bezpośrednio wygenerować wartości bajtów, które zostaną zapisane.

Ta funkcja jest tego przykładem:

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;
/

Następnie, jeśli masz kolumnę daty, możesz wstawić wartości, których normalnie nie wolno wstawiać:

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 nie działa, gdy rok przekracza normalne granice daty. Aby uzyskać wartości przechowywane w tabeli, możesz użyć DUMP aby uzyskać ciąg znaków zawierający wartości bajtów lub możesz użyć EXTRACT aby uzyskać poszczególne komponenty.

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;

wyjścia:

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<>graj tutaj




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak obsłużyć kolumnę tabeli nazwaną zarezerwowanym słowem kluczowym Sql?

  2. Jak utworzyć plik login.sql dla SQLcl

  3. Jak usunąć maszynę wirtualną z VirtualBox?

  4. Pobieranie danych wyjściowych z dbms_output.get_lines za pomocą JDBC

  5. Wyświetlaj nazwy wszystkich ograniczeń dla tabeli w Oracle SQL