按时间查数据是后台系统最高频的操作,但 oracle时间查询条件跟 MySQL 的习惯不太一样。直接拿字符串跟日期列比较,结果可能对也可能错,取决于会话的日期格式设置,换台机器跑就变样,这种问题最难排查。上线前拿几个边界日期手工核一遍,比事后补救省事。

标准写法:to_date 带格式

select * from orders   where create_time >= to_date('2024-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')     and create_time < to_date('2024-02-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss');

格式串里的分钟是 mi 不是 mm,mm 是月份,写混了查出来的范围直接错位,这是最高频的笔误。小时用 hh24 还是 hh 也有讲究,12 小时制不带上午下午标记,早晚能差十二个小时。

查当天和近几天

查今天的数据,别在列上套 trunc。trunc(create_time) = trunc(sysdate) 这种写法索引用不上,数据量一上来就慢。改成范围判断:create_time 大于等于 trunc(sysdate),并且小于 trunc(sysdate) + 1。近七天就是 create_time >= sysdate - 7,sysdate 带时分秒,从七天前的同一时刻起算,要按整天算就再套一层 trunc。

between 和隐式转换

between 包含两个边界值,按天查容易把第二天凌晨零点整那条重复算进来,跨系统对账对不上数,多半是边界没处理干净。字符串直接跟日期列比较会触发隐式转换,格式不符直接报 ORA-01861,老项目里不同环境的 nls_date_format 设置不一样,同一句 SQL 两边跑出不同结果也常有。

习惯固化成三条:时间条件用 to_date 带明确格式,列上不套函数,边界用大于等于加小于。做到这三条,oracle时间查询条件基本不会再出幺蛾子。