Oracle TO_DATE: работает в SELECT;Недопустимый месяц в предложении WHERE - PullRequest
0 голосов
/ 22 февраля 2019

Я написал запрос, который состоит из 2 подзапросов.Подзапросы форматируют результирующие имена полей и типы данных, чтобы они были идентичными.Основным запросом является прямой UNION.

Оба подзапроса получают данные с размещенного сервера Oracle;мы не контролируем структуру базы данных.Один из двух подзапросов использует строковый тип данных, чтобы содержать DateTime.Я использую следующий код в SELECT, чтобы преобразовать значение в DateTime и добавить 2 часа для настройки часовых поясов:

TO_DATE(TCF.TRANS_DATE, 'MM-DD-YYYY HH24:MI:SS') + 2/24 AS TRANS_DT,

Это дает правильное значение.

Вот морщинка:Идентичный TO_DATE в предложении WHERE приводит к ошибке ORA-01843: недопустимый месяц.Вот полное предложение WHERE:

WHERE TO_DATE(TCF.TRANS_DATE, 'MM-DD-YYYY HH24:MI:SS') + 2/24 >= {?START_DT}

Очевидный вопрос: почему вышеупомянутое работает в SELECT, но выдает эту ошибку в предложении WHERE?

Значение в поле отформатированокак указано в операторе TO_DATE.Если бы я не ожидал, что оператор SELECT выдаст ошибку, но при удалении предложения WHERE ошибки нет.

Я пытался добавить TRUNC () в предложение WHERE, поскольку параметр {? START_DT} является типом данных Date.Я также жестко запрограммировал допустимую дату вместо использования параметра.Ни один из них не повлиял на ошибку.

Завершение предложения WHERE для второго подзапроса - это все, что мне остается для завершения этого проекта и продолжения.Я использую Crystal Reports со зрелым и надежным соединением для доступа к базе данных.Любые идеи или предложения приветствуются.

Для вашей информации, вот полный запрос:

SELECT DISTINCT TCF.TRIPCARD_UNIT_NO AS UNIT_NO,
TO_DATE(TCF.TRANS_DATE, 'MM-DD-YYYY HH24:MI:SS') AS TRANS_DT2,
TCF.ODOMETER AS METER
FROM MFIVE.VIEW_TRIPCARD_FAILED_TRANS TCF
WHERE TO_DATE(TCF.TRANS_DATE, 'MM-DD-YYYY HH24:MI:SS') >= TO_DATE('02-01-2019 00:00:00', 'MM-DD-YYYY HH24:MI:SS')

Из-за разочарования я проанализировал значения месяца, дня и года из строки TRANS_DT.Там не было значений за пределами допустимого диапазона;в частности, ВСЕ месяцы были ожидаемыми значениями от 1 до 12.

Я создал новый оператор TO_DATE в предложении WHERE для вышеуказанных составных частей.Проверил и дважды проверил форматирование ... и я получил ту же ошибку.

Мне кажется, что TO_DATE не разрешен в предложении WHERE.Кто-нибудь еще слышал об этом ограничении?Любой способ создать переменную DateTime в SQL и передать ее в предложение WHERE?

UPDATE # 3:

Оставив предложение WHERE пропущенным, я использовал оставшуюся часть запроса как подзапрос ииспользовал EXTRACT MONTH FROM TRANS_DT для оператора SELECT.Этот подзапрос прекрасно выполнялся и создавался для целых чисел от 1 до 12. Это еще раз подтверждает, что в нем НЕТ неправильных дат.

Расширяя концепцию подзапроса, я попытался применить предложение WHERE с помощью этого оператора: WHERE TRUNC(TCF2.TRANS_DT) >= TO_DATE('02/01/2019', 'MM/DD/YYYY') Это произвелота же ошибка!Я чувствую запах жука, но, черт возьми, я знаю, что это такое.

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Пожалуйста, проверьте тип данных при уравнении или совпадении:

WITH S_DT AS 
(
SELECT TO_DATE(TO_CHAR(SYSDATE,'MM-DD-YYYY HH24:MI:SS'), 'MM-DD-YYYY HH24:MI:SS') START_DT FROM DUAL
),
TAB AS
(
SELECT TO_DATE(TO_CHAR(SYSDATE,'MM-DD-YYYY HH24:MI:SS'), 'MM-DD-YYYY HH24:MI:SS') + 2/24 AS TRANS_DT FROM DUAL
UNION ALL
SELECT TO_DATE(TO_CHAR(SYSDATE,'MM-DD-YYYY HH24:MI:SS'), 'MM-DD-YYYY HH24:MI:SS') - 2/24 FROM DUAL
UNION ALL
SELECT TO_DATE(TO_CHAR(SYSDATE,'MM-DD-YYYY'), 'MM-DD-YYYY') + 2/24 FROM DUAL
)
SELECT * FROM TAB,S_DT WHERE TAB.TRANS_DT >= S_DT.START_DT;

Выход:

TRANS_DT  START_DT 
--------- ---------
2/22/2019 2:09:39 PM    2/22/2019 12:09:39 PM

ИЛИ, вы также можете попробовать эту функцию NEW_TIME для изменения time zone.

SELECT SYSDATE, 
       NEW_TIME(SYSDATE, 'GMT', 'EST') 
FROM dual;

Выход:

SYSDATE   NEW_TIME(SYSDATE,'GMT','EST')
--------- -----------------------------
2/22/2019 12:10:10 PM   2/22/2019 7:10:10 AM
0 голосов
/ 22 февраля 2019

Я могу вспомнить две вероятные причины:

Во-первых, вы запускаете запрос, но просматриваете только несколько строк результатов, а не весь набор результатов.Строки, которые вы видите, не имеют проблемы с датой.Если вы прокрутите до конца, то увидите проблему.

Вторая причина заключается в том, что выражения select запускаются после фильтрации all (по крайней мере, в некоторых случаях).Неправильные значения могут быть отфильтрованы другими условиями фильтрации.Когда выражение перемещается в предложение where, все данные могут быть переданы через это условие.

...