You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确使用Oracle的to_char?解决时间差格式化多余前缀问题

解决方法

问题出在两个TIMESTAMP相减后得到的是INTERVAL类型,Oracle中直接对INTERVAL调用TO_CHAR()时,默认格式会包含多余的年/月字段(就是你看到的+000000000),而且hh24:mi:SS.FF这类DATE/TIMESTAMP的格式语法对INTERVAL不生效,所以才会出现不符合预期的结果。

直接通过EXTRACT()拆分INTERVAL的各个时间部分再拼接,就能得到你需要的格式:

UPDATE MY_TABLE
SET ENDTIME = COALESCE(:ENDTIME, ENDTIME),
    ELAPSEDTIME = EXTRACT(DAY FROM (CAST (:ENDTIME AS TIMESTAMP(6)) - STARTTIME)) || 'd ' ||
        LPAD(EXTRACT(HOUR FROM (CAST (:ENDTIME AS TIMESTAMP(6)) - STARTTIME)), 2, '0') || ':' ||
        LPAD(EXTRACT(MINUTE FROM (CAST (:ENDTIME AS TIMESTAMP(6)) - STARTTIME)), 2, '0') || ':' ||
        LPAD(FLOOR(EXTRACT(SECOND FROM (CAST (:ENDTIME AS TIMESTAMP(6)) - STARTTIME))), 2, '0') || '.' ||
        LPAD(TRUNC((EXTRACT(SECOND FROM (CAST (:ENDTIME AS TIMESTAMP(6)) - STARTTIME)) - FLOOR(EXTRACT(SECOND FROM (CAST (:ENDTIME AS TIMESTAMP(6)) - STARTTIME)))) * 1000), 3, '0')
WHERE MISSIONID = :MISSIONID

关键说明

  • EXTRACT()可以精准提取INTERVAL类型中的日、时、分、秒数值,其中秒需要拆分为整数部分和小数部分,通过乘以1000后取整得到三位毫秒值。
  • LPAD()用来保证时、分、秒为两位数字,毫秒为三位数字,不足时自动补0,完全匹配你要的0d 12:08:16.132格式。

如果觉得重复写时间差表达式太啰嗦,也可以用WITH子句简化(Oracle 12c及以上版本支持):

WITH mission_diff AS (
    SELECT 
        MISSIONID,
        CAST (:ENDTIME AS TIMESTAMP(6)) - STARTTIME AS diff
    FROM MY_TABLE
    WHERE MISSIONID = :MISSIONID
)
UPDATE MY_TABLE t
SET ENDTIME = COALESCE(:ENDTIME, t.ENDTIME),
    ELAPSEDTIME = EXTRACT(DAY FROM md.diff) || 'd ' ||
        LPAD(EXTRACT(HOUR FROM md.diff), 2, '0') || ':' ||
        LPAD(EXTRACT(MINUTE FROM md.diff), 2, '0') || ':' ||
        LPAD(FLOOR(EXTRACT(SECOND FROM md.diff)), 2, '0') || '.' ||
        LPAD(TRUNC((EXTRACT(SECOND FROM md.diff) - FLOOR(EXTRACT(SECOND FROM md.diff))) * 1000), 3, '0')
FROM mission_diff md
WHERE t.MISSIONID = md.MISSIONID

内容的提问来源于stack exchange,提问作者Danielps1818

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:49:57