【问题标题】:Reason for using trunc function on dates in Oracle在 Oracle 中对日期使用 trunc 函数的原因
【发布时间】:2014-06-27 11:29:43
【问题描述】:

我目前正在从事一个有关 Oracle 数据库的项目。我在应用程序代码中观察到几乎从不直接使用日期。相反,它们总是与 trunc 函数(TRUNC(SYSDATE)、TRUNC(event_date) 等)结合使用

谁能解释使用 trunc 函数而不是直接使用日期的原因?

【问题讨论】:

  • 因为 Oracle 中的 DATE 也包含时间部分。我猜开发人员希望确保在与“真实”日期进行比较时忽略此时间
  • TRUNC() 还接受用于重置其他日期组件的可选参数See here

标签: sql oracle


【解决方案1】:

Oracle 中的DATE 不仅有日期部分,还有时间部分。在查询数据时,这可能会导致令人惊讶的结果,例如查询

with v_data(pk, dt) as (
  select 1, to_date('2014-06-25 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual union all
  select 2, to_date('2014-06-26 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual union all  
  select 3, to_date('2014-06-27 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual)
select * from v_data where dt = date '2014-06-25'  

将不返回任何行,因为您在午夜与 2014-06-25 进行比较。

通常的解决方法是使用TRUNC() 去掉时间部分:

with v_data(pk, dt) as (
  select 1, to_date('2014-06-25 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual union all
  select 2, to_date('2014-06-26 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual union all  
  select 3, to_date('2014-06-27 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual)
select * from v_data where trunc(dt) = date '2014-06-25'  

解决此问题的其他不太常用的方法包括:

  • to_char('YYYY-MM-DD') 转换两个日期并检查是否相等
  • 使用 between 子句:WHERE dt between date '2014-06-25' and date '2014-06-26'

【讨论】:

    【解决方案2】:

    您使用trunc() 函数删除日期的时间部分。默认情况下,Oracle 中的date 数据类型同时存储日期和时间。

    trunc() 函数还采用格式参数,因此您可以删除日期的其他组成部分,而不仅仅是时间。例如,您可以截断到最近的小时。但是,没有格式,目的是去掉时间分量。

    【讨论】:

      【解决方案3】:

      如果您为表中的列(例如 event_date)建立了索引,请避免在该列上使用 trunc,因为如果这样做,Oracle 将无法使用该索引(否则,您可以创建基于函数的索引)

      所以不要这样做:

      选择 * 来自我的表 其中 trunc(event_date)

      而是这样做

      选择 * 来自我的表 其中 event_date

      在第二种情况下,Oracle 可以在 event_date 上对索引进行范围扫描,在第一种情况下,它必须进行全表扫描。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-17
        • 2021-10-27
        • 1970-01-01
        • 1970-01-01
        • 2014-08-23
        • 2012-04-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多