Oracle по умолчанию формат даты - PullRequest
0 голосов
/ 03 мая 2018

Первый раз с использованием Oracle SQL (я привык к MySQL). Я нахожу противоречивую информацию о том, что формат даты по умолчанию. После нескольких попыток использования TO_DATE с моими операторами INSERT INTO my_table я наконец нашел базу данных, которую я использую, ожидает DD-MON-YY (т.е. 25-JAN-18). Тем не менее, на различных страницах здесь, в stackoverflow и в других местах, я вижу некоторые, которые говорят, что по умолчанию используется ГГГГММДД или ДД / ММ / ГГГГ или ГГГГ-ММ-ДД. Почему так много противоречивых фрагментов информации?

Ответы [ 4 ]

0 голосов
/ 04 мая 2018

При вставке даты с помощью TO_DATE нужно только позаботиться о том, как ее проанализировать.

Пример:
Что не будет работать
to_date('31-03-2016','dd-mon-yyyy')

Что будет работать
to_date('31-03-2016','dd-mm-yyyy') to_date('31-Mar-2016','dd-Mon-yyyy')

Дата, которую вы передаете to_date, и формат должен совпадать.
31 - dd
Mar - Mon
2016 - yyyy

0 голосов
/ 03 мая 2018

ДАТЫ - это ДАТЫ - формат определяет, как ДАТА будет отображаться при запросе ваших данных.

Если вы не предоставите формат и не используете функцию TO_CHAR, мы предоставим ДАТУ обратно в NLS_DATE_FORMAT по умолчанию, который определен в базе данных, но также может быть указан для вашего сеанса.

Для вашей сессии -

select * from NLS_SESSION_PARAMETERS
where PARAMETER = 'NLS_DATE_FORMAT';

У меня 'DD-MON-YYYY', поэтому, когда я запрашиваю SYSDATE:

SQL> select sysdate from dual;

SYSDATE    
-----------
03-MAY-2018

При работе с датами обычно рекомендуется НЕ использовать конкретный формат даты. Так что, когда и INSERT или SELECT данные с датами, быть EXPLICIT. Например.

SQL> drop table JUST_DATES;

Table JUST_DATES dropped.

SQL> 
SQL> create table JUST_DATES (
  2      DATE1 date
  3  );

Table JUST_DATES created.

SQL> 
SQL> insert   into JUST_DATES values ( to_date('01-01-2018','MM-DD-YYYY') );

1 row inserted.

SQL> 
SQL> select to_char(
  2      DATE1,
  3      'MON/DD/RR'
  4  )
  5    from JUST_DATES;

TO_CHAR(DATE1,'MON
------------------
JAN/01/18

Теперь, чтобы ответить на ваш вопрос - что по умолчанию? Ну, это зависит.

Он получен из вашего NLS_TERRITORY ( документы )

Но, если вы помните лучшие практики, и вы никогда не предполагаете, что по умолчанию, и вы четко указали свои форматы даты при работе с DATE, у вас должно быть все в порядке.

Лучшее руководство по этой теме - наше Руководство по поддержке глобализации. Это интересующий вас раздел.

0 голосов
/ 04 мая 2018

A DATE не имеет формата - он хранится внутри как 7-байтов , представляющих год (2 байта) и месяц, день, час, минуту и ​​секунду (1 байт каждый).

'25-JAN-18' это не дата - это текстовый литерал.

Когда вы делаете:

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

Oracle постарается помочь и выполнить неявное приведение строки к дате, используя параметр NLS_DATE_FORMAT для сеанса пользователя в качестве модели формата. Таким образом, ваше утверждение будет неявно преобразовано в:

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

Любой пользователь может установить свои параметры NLS в своем собственном сеансе (поэтому никогда не следует полагаться на неявное преобразование, поскольку каждый пользователь может иметь разные настройки для своего собственного сеанса и может изменять значения в середине сеанса) , Вместо этого вы должны:

  • Использовать литерал даты:

    DATE '2018-01-25'
    
  • Использовать литерал Timestamp

    TIMESTAMP '2018-01-25 01:23:45'
    
  • Используйте TO_DATE( date_string, format_string [, nls_values] ) и явно используйте модель формата:

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

Если вы хотите изменить NLS_DATE_FORMAT в своем сеансе, тогда вы можете использовать:

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

Какой формат даты по умолчанию?

Поскольку DATE не имеет формата, этот вопрос не имеет смысла. Вместо этого, если мы спросим:

Какой параметр сеанса по умолчанию NLS_DATE_FORMAT используется Oracle для преобразования между строками и датами?

Это зависит от параметра сеанса NLS_TERRITORY (поэтому зависит от того, где вы находитесь в мире):

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;

Выводит формат даты и список территорий, соответствующих этому формату:

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
0 голосов
/ 03 мая 2018

Oracle, как и другие базы данных, позволяет установить формат по умолчанию. Стандартным форматом является (обычно) DD-MON-RR, где «RR» обозначает год с двумя цифрами. Это довольно паршивый формат с точки зрения двусмысленности (год из двух цифр?) И интернационализации (для каких стран это действительно дефолт?). Но Oracle существует уже очень давно.

Стандартные форматы также определены ISO, Международной организацией по стандартизации. Они остановились на чем-то более похожем на YYYY-MM-DD. На самом деле дефисы необязательны, но я думаю, что они делают дату намного более читаемой.

Oracle принимает константы в этом формате, если вы используете DATE:

select DATE '2018-01-25'

Это очень удобно. Во-первых, приятно поддерживать разумные стандарты. Во-вторых, код безопасен независимо от настроек интернационализации. Документация Oracle, конечно, подробно описывает это; здесь это одно место для начала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...