在Oracle中使用截断函数的原因

时间:2014-06-27 11:29:43

标签: sql oracle

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

任何人都可以解释使用截断函数而不是直接使用日期的原因吗?

3 个答案:

答案 0 :(得分:4)

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')转换这两个日期并检查相等性
  • 使用条款:WHERE dt between date '2014-06-25' and date '2014-06-26'

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

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

所以不要这样做:

选择* 来自mytable trunc(event_date)<日期' 2014-01-01'

但改为

选择* 来自mytable event_date<日期' 2014-01-02'

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