PL/SQL 问题:通过业务对象报告选择时出现无效月份错误

发布于 2024-09-11 04:46:18 字数 786 浏览 1 评论 0原文

这可能并不像应有的那么复杂,但与 SQL Developer 相比,Business Objects 在类型的使用方式方面似乎非常非常严格。以下是有问题的语句的一部分:

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 DATE 通过以下方式填充:

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

为什么从 Business Objects 提取数据时出现“无效月份”错误?我已经发现业务对象对类型非常严格,所以我想知道我在这里是否做错了什么。所有这些在 SQL Developer 中都运行良好,但我必须一遍又一遍地调整此语句,以尝试使其在 Business Objects 使用它时正常工作。

This probably isn't as complicated as it should be, but Business Objects seems to be very, very strict in how types are used versus SQL Developer. Here's the piece of the statement in question:

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) is filled via:

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

w.last_day DATE is filled via:

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

Why am I getting a Not Valid Month error when pulling from Business Objects? I've already found the Business objects is way strict on types, so I'm wondering if I'm doing something wrong here. All of this works fine in SQL developer, but I've had to tweak this statement over and over again to try to get it to work when Business Objects uses it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一场春暖 2024-09-18 04:46:19

您依赖于从字符串到日期的隐式转换,这始终是一个坏主意。

如果您必须先转换为字符串,然后再转换回日期,请始终使用 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 ,它将继续工作。

You're relying on implicit conversion from strings to dates, which is always a bad idea.

If you have to convert to a string then back to a date, always use to_date and a date mask. Otherwise you're depending on the NLS variables, which can be changed within a session (almost certainly the cause of your problem).

However, in this case, you don't have to. Your condition can be simplified to:

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

As @APC pointed out, if your field contains a time component, you'll want to get everything through the end of the last day of the month. This can be achieved several ways:

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)

I tend to prefer the last version as it'll continue to work if you decide to change the field to a TIMESTAMP down the road.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文