Oracle
 sql >> Database >  >> RDS >> Oracle

Formato DATE predefinito di Oracle

Una DATE non ha formato:è memorizzato internamente come 7 byte che rappresentano anno (2 byte) e mese, giorno, ora, minuti e secondi (1 byte ciascuno).

'25-JAN-18' non è una data - è un testo letterale.

Quando lo fai:

INSERT INTO table_name ( date_column ) VALUES ( '25-JAN-18' );

Oracle cercherà di essere utile ed eseguire un cast implicito da una stringa a una data utilizzando NLS_DATE_FORMAT parametro per la sessione dell'utente come modello di formato. Quindi, la tua affermazione verrà convertita implicitamente in:

INSERT INTO table_name ( date_column ) VALUES (
  TO_DATE(
    '25-JAN-18',
    ( SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT' )
  )
);

Qualsiasi utente può impostare i propri parametri NLS nella propria sessione (quindi dovresti mai fare affidamento sulla conversione implicita in quanto ogni utente può avere impostazioni diverse per la propria sessione e può modificare i valori a metà sessione). Invece dovresti:

  • Usa una data letterale:

    DATE '2018-01-25'
    
  • Usa un timestamp letterale

    TIMESTAMP '2018-01-25 01:23:45'
    
  • Usa TO_DATE( date_string, format_string [, nls_values] ) e utilizzare esplicitamente un modello di formato:

    TO_DATE( '25-JUN-18', 'DD-MON-RR' )
    

Se vuoi cambiare il NLS_DATE_FORMAT nella tua sessione puoi usare:

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';

Qual è il formato della data predefinito?

Da una DATE non ha un formato, questa domanda non ha senso. Invece se chiediamo:

Qual è il NLS_DATE_FORMAT predefinito parametro di sessione utilizzato da Oracle per convertire tra stringhe e date?

Dipende dal NLS_TERRITORY parametro di sessione (quindi dipende da dove ti trovi nel mondo):

SET SERVEROUTPUT ON;

VARIABLE cur REFCURSOR;

DECLARE
  territories SYS.ODCIVARCHAR2LIST;
  formats     SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST();
BEGIN
  select value
  BULK COLLECT INTO territories
  from v$nls_valid_values
  where parameter = 'TERRITORY'
  order by value;

  formats.EXTEND( territories.COUNT );
  FOR i IN 1 .. territories.COUNT LOOP
    EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_TERRITORY='''||territories(i)||'''';

    SELECT value
    INTO   formats(i)
    FROM   NLS_SESSION_PARAMETERS
    WHERE  PARAMETER = 'NLS_DATE_FORMAT';
  END LOOP;

  OPEN :cur FOR
  SELECT CAST( f.format AS VARCHAR2(12) ) AS format,
         LISTAGG( t.territory, ', ' ) WITHIN GROUP ( ORDER BY t.territory ) AS territories
  FROM   ( SELECT ROWNUM AS rn, COLUMN_VALUE AS territory FROM TABLE( territories ) ) t
         INNER JOIN
         ( SELECT ROWNUM AS rn, COLUMN_VALUE AS format FROM TABLE( formats ) ) f
         ON ( f.rn = t.rn )
  GROUP BY f.format;
END;
/

PRINT :cur;

Emette il formato della data e l'elenco dei territori corrispondenti a quel formato:

FORMAT       TERRITORIES
------------ ------------------------------------------------------------------
DD MON RRRR  THAILAND
DD-MM-RR     ALGERIA, BAHRAIN, INDIA, MOROCCO, THE NETHERLANDS, TUNISIA
DD-MM-RRRR   BANGLADESH, INDONESIA, ROMANIA, VIETNAM
DD-MON-RR    AMERICA, CHINA, HONG KONG, IRELAND, ITALY, PAKISTAN, TAIWAN,
             UNITED KINGDOM
DD-MON-RRRR  ISRAEL
DD.MM.RR     AUSTRIA, BELARUS, CIS, CROATIA, CZECH REPUBLIC, CZECHOSLOVAKIA,
             GERMANY, RUSSIA, SLOVAKIA, SLOVENIA, SWITZERLAND
DD.MM.RRRR   ALBANIA, AZERBAIJAN, ESTONIA, FINLAND, FYR MACEDONIA, ICELAND,
             KAZAKHSTAN, MACEDONIA, NORWAY, SERBIA AND MONTENEGRO, UKRAINE,
             YUGOSLAVIA
DD.MM.RRRR.  MONTENEGRO, SERBIA
DD.fmMM.RRRR ARMENIA
DD/MM/RR     AFGHANISTAN, BELGIUM, BRAZIL, CAMEROON, CATALONIA, CHILE, COLOMBIA,
             CONGO BRAZZAVILLE, CONGO KINSHASA, COSTA RICA, CYPRUS, DJIBOUTI,
             EGYPT, EL SALVADOR, FRANCE, GABON, GREECE, GUATEMALA, HONDURAS,
             IRAQ, IVORY COAST, JORDAN, KUWAIT, LEBANON, LIBYA, LUXEMBOURG,
             MAURITANIA, MEXICO, NEW ZEALAND, NICARAGUA, OMAN, PANAMA, PERU,
             PUERTO RICO, QATAR, SAUDI ARABIA, SINGAPORE, SOMALIA, SPAIN, SUDAN,
             SYRIA, UNITED ARAB EMIRATES, URUGUAY, VENEZUELA, YEMEN
DD/MM/RRRR   ARGENTINA, BAHAMAS, BERMUDA, ECUADOR, MALAYSIA, SENEGAL, TURKEY,
             UGANDA, ZAMBIA
DD/MON/RR    AUSTRALIA, SOUTH AFRICA, UZBEKISTAN
DD/fmMM/RRRR LAOS, NIGERIA
MM/DD/RRRR   PHILIPPINES
RR-MM-DD     CANADA, DENMARK, JAPAN
RR-MON-DD    HUNGARY
RR.MM.DD     PORTUGAL
RR/MM/DD     KOREA, POLAND
RRRR-MM-DD   BULGARIA, SWEDEN
RRRR-fmMM-DD CAMBODIA
RRRR.MM.DD   LATVIA, LITHUANIA
RRRR/fmMM/fm IRAN, SRI LANKA
fmDD-MM-RR   BOLIVIA
fmDD/MM/RR   PARAGUAY
fmDD/MM/RRRR BELIZE, ETHIOPIA, MALTA, NEPAL
fmDD/fmMM/RR MALDIVES
fmMM.DD.RRRR BOSNIA AND HERZEGOVINA
fmMM/DD/RRRR KENYA, TANZANIA