Выражение Oracle SQL TO_DATE выдает ошибку нечислового символа ORA-01858

#sql #oracle #crystal-reports #to-date

#sql #Oracle #crystal-отчеты #на сегодняшний день

Вопрос:

Чтобы отчет функционировал должным образом, я должен преобразовать параметры даты в рабочем запросе Oracle SQL со строками для отчета. Хотя это может показаться странным — в конце концов, это даты — использование строк является обязательным условием для запуска отчета в нашей размещенной базе данных. Отчет прекрасно выполняется в Crystal Reports с параметрами даты, и имейте в виду, что фигурные скобки {} — это то, как Crystal Reports определяет параметры.

Проблема заключается в преобразовании текущего синтаксиса в синтаксис, основанный на символах. Вот выдержка из более крупного запроса; {?01_START_DT} является параметром даты в формате ММ / ДД / ГГГГ (например, 31.07.2020).:

 SELECT U."UnitNumber" AS UNIT_NO
     , U."UsingDepartment" AS USE_DEPT
     , U."UnitStatus" AS STATUS
     , (
    SELECT H.USAGE
    FROM UNIT_HIST H
    WHERE U."UNITID" = H.UNIT_ID 
    AND   H.COMPANY  = 'OKS' 
    AND   FISC_PD    = CASE WHEN EXTRACT(MONTH FROM {?01_START_DT}) >= 7 
                         THEN TO_CHAR(ADD_MONTHS({?01_START_DT}, 12), 'YYYY') || TO_CHAR(ADD_MONTHS({?01_START_DT}, -6), 'MM')
                         ELSE TO_CHAR({?01_START_DT}, 'YYYY') || TO_CHAR(ADD_MONTHS({?01_START_DT}, 6), 'MM') 
                       END
FROM VIEW_ALL_UNITS U
  

Проще всего заменить параметр строкой {?START_DT} вида ММ / ДД/ ГГГГ (например, ‘31.07.2020’, вводится без кавычек) следующим образом:

 SELECT U."UnitNumber" AS UNIT_NO
     , U."UsingDepartment" AS USE_DEPT
     , U."UnitStatus" AS STATUS
     , (
    SELECT H.USAGE
    FROM UNIT_HIST H
    WHERE U."UNITID" = H.UNIT_ID 
    AND   H.COMPANY  = 'OKS' 
    AND   FISC_PD    = CASE 
                         WHEN EXTRACT(MONTH FROM TO_DATE({?START_DT}, 'MM/DD/YYYY') >= 7 
                         THEN TO_CHAR(ADD_MONTHS(TO_DATE({?START_DT}, 'MM/DD/YYYY'), 12), 'YYYY') || TO_CHAR(ADD_MONTHS(TO_DATE({?START_DT}, 'MM/DD/YYYY'), -6), 'MM')
                         ELSE TO_CHAR(TO_DATE({?START_DT}, 'MM/DD/YYYY'), 'YYYY') || TO_CHAR(ADD_MONTHS(TO_DATE({?START_DT}, 'MM/DD/YYYY'), 6), 'MM') 
                      END
FROM VIEW_ALL_UNITS U
  

За исключением того, что это приводит к ошибке «нечислового символа» ORA-01858!

Я пробовал ооочень много вещей, но безуспешно:

  • Изменения во входной строке (даже если она соответствует формату)
  • Добавление компонента времени к формату и входной строке
  • Добавление необязательной части NLZ TO_DATE
  • Упрощение строки путем удаления инструкций EXTRACT и MONTH (для устранения неполадок)
  • Изменение выражения РЕГИСТРА (для устранения неполадок) на:
 FISC_PD = CASE WHEN TO_DATE({?START_DT}, 'MM/DD/YYYY') = TO_DATE('07/01/2020', 'MM/DD/YYYY') THEN 
  

Излишне говорить, что ошибка сохраняется, независимо от того, что я пытаюсь.

Как я упоминал ранее, это запрашивает базу данных в размещенной системе, к которой у меня нет физического или электронного доступа. Эти запросы относятся к базе данных отчетов. Ошибка не предоставляет номер строки или любую другую информацию, полезную для устранения неполадок.

Есть идеи, что может быть причиной этой проблемы?

Комментарии:

1. Я полагаю, что TO_DATE({?START_DT}, ‘ММ / ДД / ГГГГ’) должен иметь параметр date в кавычках: TO_DATE(‘{?START_DT}’, ‘ММ / ДД / ГГГГ’)

2. Я бы подумал, что добавление кавычек вызовет эту ошибку, а не решит ее, если она уже привязана к строке? В любом случае … чтобы уточнить, {?01_START_DT} передается как фактическая дата и {?START_DT} передается как строка, определенно в формате MM / DD / YYYY, верно? Что произойдет, если вы запустите свои запросы непосредственно в БД, но измените все {?01_START_DT} на date '2020-08-01' и все {?START_DT} на '08/01/2020' ? Похоже, в примерах не хватает пары закрывающих скобок, что может не иметь значения, но немного сбивает с толку. И можете ли вы попробовать это с гораздо более простым запросом, чтобы сузить его?

3. Возможно, глупый вопрос — когда вы генерируете строку для передачи, вы включаете кавычки внутри этой строки? т. Е. Является ли фактическое значение этой строки как 08/01/2020 или '08/01/2020' ? ( Краткая демонстрация разницы }

4. @spacetanker — вы уверены, что ничего не добавляется по пути? Мы ничего не знаем о вашей ситуации, кроме запроса, поэтому пытаемся косвенно исключить ситуацию. Можете ли вы запустить версию, которая просто выполняет select {?START_DT} from dual , чтобы посмотреть, что она возвращает? Как я уже сказал, может быть далеко от базы, но…

5. Я не понимаю, как часть {?01_START_DT} заменяется датой. То, что вы показываете, — это запросы SQL, за исключением этих частей. Какой инструмент вы используете для замены этих частей? В Oracle я бы предпочел ожидать привязки переменных, например, :START_DT вместо этих скобок.