【问题标题】:Oracle - Should I convert dates with to_date before comparison?Oracle - 我应该在比较之前用 to_date 转换日期吗?
【发布时间】:2013-06-04 12:26:17
【问题描述】:

在查询中,我偶然发现每个日期在进行任何比较之前都使用 to_date 函数进行了转换。有时它会导致“文字与格式字符串不匹配”错误,这与格式无关,原因在这里解释: ORA-01861: literal does not match format string

我的问题是:真的有必要使用日期转换吗?为什么在应用任何逻辑比较之前首先对其进行转换?

【问题讨论】:

  • 请向我们展示产生错误的查询以及所涉及表的表定义。

标签: sql oracle


【解决方案1】:

Oracle 不会将日期存储为日期。问题是日期上的某个时间可能会导致它们不相等。 (有关日期数据类型的信息,您可以查看文档here。)

一般来说,我们认为“2013-01-01”等于“2013-01-01”。但是,第一个日期可能是“2013-01-01 01:00:00”,第二个日期可能是“2013-01-01 02:02:02”。他们不会是平等的。更糟糕的是,它们打印出来时可能看起来一样。

您实际上不必将日期转换为字符串即可进行此类比较。您还可以使用trunc() 函数。这种数据转换可以防止数据的“不可见”时间分量干扰比较。

【讨论】:

    【解决方案2】:

    您确实应该将日期存储为实际日期(或时间戳)。如果您有表示日期的字符串,您通常需要使用 to_date 转换它们(使用指定的格式,不依赖于默认格式)。这实际上取决于您想要什么比较/日期功能。您遇到错误是因为您遇到的值不符合您指定的格式。这也是将列指定为 DATE 以存储日期的一个很好的理由。例如,

    select to_date('123', 'MM-DD-YYYY') from dual;
    

    将抛出 ORA-01861。所以你可能有 99.9% 的行是 MM-DD-YYYY,但 0.1% 会让你头疼。

    无论如何,如果你清理了这些字符串,你可以使用 to_date 和 date 函数做更多的事情。例如:

    select 
    (last_day(to_date('02-05-2009', 'MM-DD-YYYY')) - to_date('01-15-1998', 'MM-DD-YYYY')) as days_between_dates
    from dual;
    

    用字符串来做这件事并不好玩。或者也许只是找到最近的日期:

    select greatest( to_date('02-05-2009', 'MM-DD-YYYY'), to_date('12-01-1988', 'MM-DD-YYYY')) from dual;
    

    使用字符串比较会给出错误的答案:

    select greatest('02-05-2009', '12-01-1988') from dual;
    

    仅举几个例子,但最好将日期视为日期,而不是字符串。

    【讨论】:

      【解决方案3】:

      如果您有一个表示日期的字符串,请使用TO_DATE
      如果您已经有日期,请直接使用它。

      【讨论】:

      • 我有一个子查询(用于join),其中日期用to_char转换,然后在父查询中用在where子句中,用to_date转换。
      • @kyooryu:你为什么要转换成to_char放在首位?
      • @kyooryu 如果您有一个提出问题的具体示例,最好将其作为问题的一部分发布。
      • @kyooryu:认为查询或某些表的表定义会泄露任何关键信息是一种误解。
      • @a_horse_with_no_name 这不是关于什么似乎是关键信息,而是关于公司政策,我不会打破它来回答我出于好奇而提出的问题,因为它确实不会以任何方式影响我的工作。
      猜你喜欢
      • 2017-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-05
      • 2018-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多