У меня есть таблица, которая вычисляет некоторую базу мер по типу столбца 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





Вы конвертируете жало в 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;
Вы можете сохранить его как тип даты в таблице?
Ну конечно; естественно. DATE — это ДАТА, независимо от того, является ли стиль отображать григорианским или персидским.
Нет, это важно для меня, потому что в моем бизнесе все измерения должны рассчитываться в персидском режиме, и эти два календаря имеют разные день, месяц и год одновременно.
Нет, в Oracle ДАТА хранится во внутреннем формате, который не зависит от календаря. Вам нужно настроить календарь только для отображения, а не для хранения или расчетов. Если вы говорите SYSDATE + 1, то это означает завтра - как по-григориански, так и по-персидски.
можете ли вы прислать ссылку или ссылку об этом, которая предназначена только для отображения, а не для какого-либо магазина или расчета?
Проверьте это: stackoverflow.com/questions/13568193/…
@GhostMan, тебе следует прочитать эту книгу docs.oracle.com/en/database/oracle/oracle-database/19/nlspg/…
@WernfriedDomscheit спасибо, но я использую приведенный выше запрос и его работу много дней в году, и у меня возникла проблема менее десяти дней в году ...
Что вы подразумеваете под «была проблема с менее чем десятью днями в году…»? Пожалуйста, укажите проблему, с которой вы столкнулись.
Когда вы выполняете свой выбор только для 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 просто хранит дату, не заботясь о календаре, вам нужно преобразовать его в соответствующий календарь для отображения.
Для хорошего объяснения того, как оракул хранит даты, см.
Я пытаюсь использовать функцию TO_CHAR, и я знаю, что она работает. Но проблема возникает, когда я должен использовать функцию TO_DATE, чтобы сохранить ее в таблице со столбцом типа «DATE».