【问题标题】:Oracle PL/SQL - Not a valid month errorOracle PL/SQL - 不是一个有效的月份错误
【发布时间】:2018-03-15 11:10:07
【问题描述】:

我正在尝试使用 Oracle 网站上的这个 PL/SQL 脚本创建日历表: Date Dimension Data Generator

一切正常,但我无法运行第 5 节中的语句:

SELECT *
FROM TABLE(UDF_CALENDAR_GENERATOR(CAST('1-JAN-2016' AS DATE), CAST('31-DEC-2016' AS DATE)));

我得到错误:

  1. 00000 - “不是一个有效的月份”

*原因:
*行动:

我尝试使用to_date 函数(基于od this answer):

SELECT *
FROM TABLE(UDF_CALENDAR_GENERATOR(TO_DATE('14-Apr-2015', 'DD-MON-YYYY'), TO_DATE('14-May-2015', 'DD-MON-YYYY')));

但它不起作用。这句话有什么问题?

【问题讨论】:

  • 您是否按照链接页面中的建议在调用函数之前运行ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY';
  • 您是否必须将日期与写出的月份一起传递?如果没有,您可以使用数字月份值,例如to_date('14/04/2015', 'dd/mm/yyyy') 避免 nls 语言差异。如果做不到这一点,您可以使用 hekko 的解决方案来指定您传递日期的语言。
  • 不,我不必这样做,但是当我用 to_date('14/04/2015', 'dd/mm/yyyy') 替换 CAST('1-JAN-2016' AS DATE) 时,脚本失败并出现 not valid month 错误。当我设置NLS_DATE_LANGUAGE = 'Polish' 时,它也失败了。所以我认为该脚本不适用于美国以外的其他语言。
  • 'Apr' 采用英文月份名称。对于波兰语,它将是'Kwi'。 (作为来自英格兰的英语人士,我讨厌 'American' 被视为一种语言。)
  • to_date('14/04/2015', 'dd/mm/yyyy') 不应因月份无效错误而失败。您确定用脚本中的数字格式替换了指定月份的所有实例吗?

标签: sql oracle


【解决方案1】:
SELECT *
FROM TABLE(
    UDF_CALENDAR_GENERATOR(
        TO_DATE('14-Apr-2015', 'DD-MON-YYYY', 'NLS_DATE_LANGUAGE = American'), 
        TO_DATE('14-May-2015', 'DD-MON-YYYY', 'NLS_DATE_LANGUAGE = American')
    )
);

【讨论】:

    【解决方案2】:

    有人应该告诉作者,在Oracle中,date literals写成date '2016-01-01',所以查询应该是:

    select *
    from   table(udf_calendar_generator(date '2016-01-01', date '2016-12-31'));
    

    CAST() 表达式实际上是 TO_DATE(),没有指定日期格式或语言,需要运气元素才能在任何给定环境中工作。

    【讨论】:

      【解决方案3】:

      一定是日期格式问题,请确保您的日期格式为DD-MON-YYYY,并且由于您使用的是英文,请确保您的日期语言为英文:

      ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY';
      
      ALTER SESSION SET NLS_DATE_LANGUAGE = 'American';
      

      【讨论】:

      • 第二条语句解决了这个问题。谢谢。
      【解决方案4】:

      查找默认日期格式: 从 NLS_SESSION_PARAMETERS 中选择 *;

      在 sql 开发者中: 在查询开始时: 更改会话集 NLS_DATE_FORMAT = 'MM/DD/YYYY';

      在查询结束时(返回默认格式): 更改会话集 NLS_DATE_FORMAT = 'DD-MON-RR';

      但是存储过程是不同的。 开始后: 立即执行'alter session set NLS_DATE_FORMAT = ''MM/DD/YYYY''';

      在存储过程结束时,就在 'END' 之前: 立即执行'alter session set NLS_DATE_FORMAT = ''DD-MON-RR''';

      【讨论】:

        猜你喜欢
        • 2016-11-07
        • 2022-01-22
        • 1970-01-01
        • 1970-01-01
        • 2012-10-11
        • 2012-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多