Есть ошибка ORA-01861, когда я хочу изменить ее на "тип столбца даты"

У меня есть таблица, которая вычисляет некоторую базу мер по типу столбца Date. также, это должно хранить дату как персидский календарь, но в конце, когда я использую функцию TO_DATE для изменения ее типа, возникает ошибка ORA-01861 19,20,21 дня мая, в то время как такая дата уже существует, а второй месяц персидского календаря имеет 31 день. вот мой запрос:

with a as
 (select to_char(to_date('20190518', 'YYYYMMDD'),
                 'YYYYMMDD',
                 'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
    from DUAL
  UNION ALL
  select to_char(to_date('20190519', 'YYYYMMDD'),
                 'YYYYMMDD',
                 'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
    from DUAL
  UNION ALL
  select to_char(to_date('20190520', 'YYYYMMDD'),
                 'YYYYMMDD',
                 'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
    from DUAL
  UNION ALL
  select to_char(to_date('20190521', 'YYYYMMDD'),
                 'YYYYMMDD',
                 'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
    from DUAL
  UNION ALL
  select to_char(to_date('20190522', 'YYYYMMDD'),
                 'YYYYMMDD',
                 'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
    from DUAL)
SELECT TO_DATE(PERSIAN_DATE, 'YYYY/MM/DD') pers_date FROM A

моя версия базы данных оракула - Oracle 12.2.0.1.0

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
154
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы конвертируете жало в DATE, затем в строку и обратно в DATE, это бесполезно.

Попробуй это:

WITH a AS
 (SELECT TO_DATE('20190518', 'YYYYMMDD') PERSIAN_DATE
    FROM DUAL
  UNION ALL
  SELECT TO_DATE('20190519', 'YYYYMMDD') PERSIAN_DATE
    FROM DUAL
  UNION ALL
  SELECT TO_DATE('20190520', 'YYYYMMDD') PERSIAN_DATE
    FROM DUAL
  UNION ALL
  SELECT TO_DATE('20190521', 'YYYYMMDD') PERSIAN_DATE
    FROM DUAL
  UNION ALL
  SELECT TO_DATE('20190522', 'YYYYMMDD') PERSIAN_DATE
    FROM DUAL)
SELECT to_char(PERSIAN_DATE, 'YYYYMMDD', 'NLS_CALENDAR=PERSIAN') pers_date 
FROM A

или короче:

SELECT TO_CHAR(TO_DATE('20190517', 'YYYYMMDD')+LEVEL, 'YYYYMMDD', 'NLS_CALENDAR=PERSIAN') pers_date 
FROM dual
CONNECT BY LEVEL <= 5;

Или используйте литералы DATE и значения сеанса NLS:

ALTER SESSION SET NLS_CALENDAR = 'PERSIAN';
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYYMMDD'; 

SELECT DATE '2019-05-17' + LEVEL pers_date 
FROM dual
CONNECT BY LEVEL <= 5;

Я пытаюсь использовать функцию TO_CHAR, и я знаю, что она работает. Но проблема возникает, когда я должен использовать функцию TO_DATE, чтобы сохранить ее в таблице со столбцом типа «DATE».

GhostMan 21.05.2019 13:35

Вы можете сохранить его как тип даты в таблице?

GhostMan 21.05.2019 13:36

Ну конечно; естественно. DATE — это ДАТА, независимо от того, является ли стиль отображать григорианским или персидским.

Wernfried Domscheit 21.05.2019 13:40

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

GhostMan 21.05.2019 13:47

Нет, в Oracle ДАТА хранится во внутреннем формате, который не зависит от календаря. Вам нужно настроить календарь только для отображения, а не для хранения или расчетов. Если вы говорите SYSDATE + 1, то это означает завтра - как по-григориански, так и по-персидски.

Wernfried Domscheit 21.05.2019 13:57

можете ли вы прислать ссылку или ссылку об этом, которая предназначена только для отображения, а не для какого-либо магазина или расчета?

GhostMan 21.05.2019 14:02

Проверьте это: stackoverflow.com/questions/13568193/…

Wernfried Domscheit 21.05.2019 14:08

@GhostMan, тебе следует прочитать эту книгу docs.oracle.com/en/database/oracle/oracle-database/19/nlspg/‌​…

thatjeffsmith 21.05.2019 14:12

@WernfriedDomscheit спасибо, но я использую приведенный выше запрос и его работу много дней в году, и у меня возникла проблема менее десяти дней в году ...

GhostMan 21.05.2019 14:57

Что вы подразумеваете под «была проблема с менее чем десятью днями в году…»? Пожалуйста, укажите проблему, с которой вы столкнулись.

Wernfried Domscheit 21.05.2019 16:04

Когда вы выполняете свой выбор только для 18-го числа (с которым у вас не было проблем) и добавляете необработанное значение, вы увидите, что оно возвращается

with a as
     (select to_char(to_date('20190518', 'YYYYMMDD'),
                     'YYYYMMDD',
                     'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
        from DUAL)
    SELECT PERSIAN_DATE, TO_DATE(PERSIAN_DATE, 'YYYY/MM/DD') pers_date FROM A;

Persian Date    pers_date
13980228        28/FEB/98  00:00:00  

Таким образом, оракул пытается отбросить первые два символа и сделать наилучшую дату из остальных (почти уверен, что это не правильная персидская дата).

Таким образом, следуя той же логике, когда вы запускаете это для 19-го числа (мы можем получить только необработанное значение, так как на сегодняшний день произойдет ошибка)

with a as
  (select to_char(to_date('20190519', 'YYYYMMDD'),
                 'YYYYMMDD',
                 'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
    from DUAL)
SELECT PERSIAN_DATE pers_date FROM A;

Persian Date
13980229

Следуя той же логике, что и выше, отбросьте первые два символа, и вы получите 29 февраля 1998 года... это недопустимая дата.

Как отмечали другие в комментариях, Oracle просто хранит дату, не заботясь о календаре, вам нужно преобразовать его в соответствующий календарь для отображения.

Для хорошего объяснения того, как оракул хранит даты, см.

Как даты хранятся в Oracle?

Другие вопросы по теме