sql >> Base de Datos >  >> RDS >> Oracle

Formato de FECHA predeterminado de Oracle

Una DATE no tiene formato:se almacena internamente como 7 bytes que representan el año (2 bytes) y el mes, día, hora, minuto y segundo (1 byte cada uno).

'25-JAN-18' no es una fecha, es un texto literal.

Cuando lo haces:

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

Oracle intentará ser útil y realizará una conversión implícita de una cadena a una fecha utilizando el NLS_DATE_FORMAT parámetro para la sesión del usuario como modelo de formato. Entonces, su declaración se convertirá implícitamente a:

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

Cualquier usuario puede configurar sus parámetros NLS en su propia sesión (por lo que nunca confiar en la conversión implícita ya que cada usuario puede tener una configuración diferente para su propia sesión y puede cambiar los valores a mitad de la sesión). En su lugar, deberías:

  • Utilice un literal de fecha:

    DATE '2018-01-25'
    
  • Usar un literal de marca de tiempo

    TIMESTAMP '2018-01-25 01:23:45'
    
  • Use TO_DATE( date_string, format_string [, nls_values] ) y usa explícitamente un modelo de formato:

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

Si desea cambiar el NLS_DATE_FORMAT en su sesión entonces puede usar:

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

¿Cuál es el formato de fecha predeterminado?

Desde una DATE no tiene un formato, esta pregunta no tiene sentido. En cambio, si preguntamos:

¿Cuál es el NLS_DATE_FORMAT predeterminado? parámetro de sesión que usa Oracle para convertir entre cadenas y fechas?

Depende del NLS_TERRITORY parámetro de sesión (por lo que depende de dónde se encuentre en el mundo):

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;

Muestra el formato de fecha y la lista de territorios correspondientes a ese 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