【问题标题】:NOT A VALID MONTH ERROR IN ORACLE FOR BELOW CODE以下代码在 ORACLE 中出现无效月份错误
【发布时间】:2020-12-15 01:50:41
【问题描述】:

我收到以下代码的“不是有效月份”错误:

SELECT last_name, employee_id, hire_date
FROM employees
WHERE EXTRACT(YEAR FROM TO_DATE(hire_date, 'DD-MON-RR')) > 1998
ORDER BY hire_date;

【问题讨论】:

  • hire_date是什么数据类型?
  • @TBose 你永远不应该在已经是 DATE 数据类型的东西上使用to_date(),因为我怀疑你在这里做。当您这样做时,Oracle 会这样做:to_date(to_char(<DATE value>, <NLS_DATE_FORMAT parameter value>), <supplied format, or if none supplied, NLS_DATE_FORMAT parameter value>)。永远不要这样做,因为您可能在隐式转换之间存在冲突的格式(就像您在此处所遇到的那样),您可能会丢失信息或获取错误的信息,并且您会迫使数据库执行不必要的工作。

标签: sql oracle datetime query-optimization where-clause


【解决方案1】:

我看不出在这里使用extract() 的意义。这是次优的,因为数据库需要将该函数应用于列中的所有值,然后才能进行过滤。我建议直接过滤文字日期:

where hire_date >= date '1999-01-01'

此谓词将利用hire_date 上的索引。您甚至可以向索引添加更多列以完全覆盖查询,例如:(hire_date, last_name, employee_id)

【讨论】:

    【解决方案2】:

    假设这是 Oracle 教程中的 employees 表,hire_date 已经是 date 列。你不需要在上面使用to_date

    SELECT   last_name, employee_id, hire_date
    FROM     employees
    WHERE    EXTRACT(YEAR FROM hire_date) > 1998
    ORDER BY hire_date;
    

    【讨论】:

    • @mohdatif 在原始 sn-p 中,日期使用数据库的默认日期格式隐式转换为字符串,然后使用 to_date 调用显式转换为日期。如果默认日期格式与to_date 调用中指定的显式格式不匹配,您将收到此错误
    • 我添加了来自 Oracle 的实时查询与 to_date
    • 除了 cmets 关于 never, ever 对已经是 DATE 数据类型的列使用 to_date 之外,您不应该使用 RR 格式掩码。这意味着作为 Y2k 错误的临时创可贴。二十年后,我们不应该仍然使用临时修复。而且当然不是两位数的形式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多