使用 to_date() 的 Oracle 查询得到 ORA-01858

时间:2021-05-18 21:37:10

标签: sql oracle datetime

我正在使用以下语法将字符字段转换为“Toad for Oracle”中的日期:

to_date(value_char, 'MM/DD/YYYY HH:MI:SS AM','NLS_DATE_LANGUAGE = American')

我收到错误:

<块引用>

ORA-01858: 在需要数字的地方发现了一个非数字字符'

我相信错误可能是个位数的月份和天数。例如,这里是字段的几个值:

3/3/2020 9:56:00 AM
12/14/2020 10:39:00 AM

是否有特定的语法来指定没有前面的“0”。

3 个答案:

答案 0 :(得分:3)

您没有提供数据库版本,但如果您使用的是 12.2 或更高版本,以下内容应该会告诉您问题出在哪里。

select value_char
from table
where to_date(value_char default null on conversion error,
          'MM/DD/YYYY HH:MI:SS AM','NLS_DATE_LANGUAGE = American') is null;

答案 1 :(得分:3)

<块引用>

最初,我使用 where 语句来过滤所需的类别。我还尝试了指定类别的子查询(在 from 子句中),但仍然收到相同的错误。

Oracle 不一定会在尝试数据转换之前应用所有过滤器;特别是如果您在过滤器/连接条件中使用转换后的日期值。

幸运的是 case expressions use short-circuit evaluation,因此您可以使用 1 来限制尝试转换的时间:

case when value_type = 'DATE' then
  to_date(value_char, 'MM/DD/YYYY HH:MI:SS AM')
end

... 其中 value_type = 'DATE' 是您用来识别包含合适值的行的任何类别检查 - 当然,您仍然希望您没有格式错误的数据,但这就是将所有内容存储为字符串的成本。

如果您使用的是 12cR2+,那么@Gary 建议使用 the to_date() function on conversion error 子句 with 也可以使用 - 单独使用,或者与此结合使用,因此它只能捕获格式错误的值。

答案 2 :(得分:0)

在 Given-case 中,您不能使用直接适合所有人的单一简单查询。

  • 您必须根据从获得的结果行来隔离行 下面查询并对这些行集执行更新以使它们 使用 substr、lpad 或两者组合的符合条件的日期。
  • 还可以在单​​个 SQL 查询中构建复杂的“案例”

注意 我假设了列名和表名;希望你得到漂移。

select length(value_char),count(1) 
    from your_table
        group by length(value_char);