Проблема с PL / SQL: ошибка недопустимого месяца при выборе через отчет бизнес-объекта - PullRequest
0 голосов
/ 23 июля 2010

Это, вероятно, не так сложно, как должно быть, но бизнес-объекты, похоже, очень и очень строги в том, как используются типы по сравнению с SQL Developer.Вот фрагмент данного заявления:

ship_date between '01' || '-' || w_current_ora_month || '-' || to_char(to_date(w_last_day, 'DD-MON-RR HH:MI:SS AM'), 'yy') and to_char(to_date(w_last_day, 'DD-MON-RR HH:MI:SS AM'))

w_current_ora_month VARCHAR2 (3) заполняется через:

SELECT to_char(sysdate,   'MON')
  INTO w_current_ora_month
  FROM dual;

w.last_day ДАТА заполняется через:

SELECT trunc(LAST_DAY('01' || '-' || w_current_ora_month || '-' || to_char(w_year)))
    into w_last_day
    from dual

Почему при извлечении из Business Objects появляется ошибка «Недействительный месяц»?Я уже обнаружил, что бизнес-объекты очень строги по типам, поэтому мне интересно, делаю ли я здесь что-то не так.Все это прекрасно работает в SQL-разработчике, но мне приходилось настраивать это утверждение снова и снова, чтобы попытаться заставить его работать, когда его используют Business Objects.

1 Ответ

6 голосов
/ 23 июля 2010

Вы полагаетесь на неявное преобразование строк в даты, что всегда является плохой идеей.

Если вам нужно преобразовать в строку, а затем вернуться к дате, всегда используйте to_date и маску даты. В противном случае вы зависите от переменных NLS, которые могут быть изменены в течение сеанса (почти наверняка причина вашей проблемы).

Однако в этом случае вам не нужно. Ваше условие может быть упрощено до:

ship_date between trunc(sysdate,'MON') and last_day(trunc(sysdate))

Как указывал @APC, если ваше поле содержит компонент времени, вы захотите получить все до конца последнего дня месяца. Это может быть достигнуто несколькими способами:

ship_date between trunc(sysdate,'MON') 
              and last_day(trunc(sysdate))+(86399/86400)

ship_date between trunc(sysdate,'MON') 
              and add_months(trunc(sysdate,'MON'),1)-(1/86400)

ship_date >= trunc(sysdate,'MON') 
    and ship_date < add_months(trunc(sysdate,'MON'),1)

Я предпочитаю последнюю версию, так как она будет продолжать работать, если вы решите изменить поле на TIMESTAMP в будущем.

...