繁体   English   中英

Oracle SQL To_Char(interval) 没有使用我的格式字符串?

[英]Oracle SQL To_Char(interval) is not using my format string?

在 SQL 的以下位中,我想以 HH:MM:SS 格式打印一个间隔(实际上是几秒)。 我将秒数转换为间隔,然后尝试使用 TO_CHAR 日期格式。 Oracle 服务器忽略我的模式并打印一个完整的时间戳,日期和微秒中的字符为零。 我究竟做错了什么?

CASE WHEN (TR.RUN_LENGTH > 0) THEN TO_CHAR(NUMTODSINTERVAL(TR.RUN_LENGTH,'second'), 'HH24:MI:SS')
ELSE '0' END AS RUN_LENGTH,

我得到:+000000000 00:03:22.000000000

正如您所观察到的, to_char()不适用于间隔。 所以,不要考虑间隔。 相反,您有几秒钟的时间,并且想要转换为 HH:MM:SS 格式的字符串。

使用算术和字符串运算:

select lpad(floor(tr.run_length / 3600), 2, '0') || ':' || lpad(mod(floor(tr.run_length / 60),  60), 2, '0') || ':' || lpad(mod(tr.run_length, 60), 2, '0') as hhmmss
from (select 1 as run_length from dual union all
      select 10 as run_length from dual union all
      select 100 as run_length from dual union all
      select 1000 as run_length from dual union all
      select 10000 as run_length from dual union all
      select 100000 as run_length from dual 
     ) tr;

是一个 db<>fiddle。

我搜索了其他相关回复; 很明显,Oracle 实际上并没有为 TO_CHAR(DSINTERVAL) 实现用户指定的格式。 正如一些人所建议的,您可以添加一个日期,然后使用日期格式。 但如果间隔超过 24 小时,则会失败。

我最终使用了 REGEXP_SUBSTRING() 但后来遇到了 Oracle 显然不支持非捕获组的问题。 我能够拼凑出这个:

REGEXP_SUBSTR(TO_CHAR(NUMTODSINTERVAL(TR.RUN_LENGTH,'second')), '^([\+0:\ ]*)(.*)(\.)',1,1,NULL,2 )

这似乎工作得很好。 它抑制任何前导零和小数秒。

如果您的时间间隔始终少于 24 小时,那么您可以使用以下方法之一:

TO_CHAR(TRUNC(SYSDATE) + NUMTODSINTERVAL(TR.RUN_LENGTH, 'second'), 'hh24:mi:ss')

REGEXP_SUBSTR(NUMTODSINTERVAL(TR.RUN_LENGTH,'second'), '\d{2}:\d{2}:\d{2}')

否则,您需要使用EXTRACT function:

SELECT
    TO_CHAR(
       EXTRACT(DAY FROM NUMTODSINTERVAL(TR.RUN_LENGTH,'second')) * 24 
       + EXTRACT(HOUR FROM NUMTODSINTERVAL(TR.RUN_LENGTH,'second')) )
   || ':' EXTRACT(MINUTE FROM NUMTODSINTERVAL(TR.RUN_LENGTH,'second') 
   || ':' TRUNC(EXTRACT(SECOND FROM NUMTODSINTERVAL(TR.RUN_LENGTH,'second'))

如果 output 需要,您可以选择在零件周围添加LPAD(..., 2, '0')

更少的代码:

to_number(
substr(to_char((LATER_timestamp - EARLIER_timestamp),'HH24:MI:SS'), 1,10) /* this is the DAY  string */ 
) || 'd ' ||
substr(to_char((LATER_timestamp - EARLIER_timestamp),'HH24:MI:SS'),12,11) /* this is the TIME string.  Milliseconds are "FLOORED". */

示例 output 是:“2d 02:59:57.31”。

尝试这个:

TO_CHAR (TRUNC (SYSDATE) + NUMTODSINTERVAL ((TR.RUN_LENGTH, 'second'),   
    'hh24:mi:ss' )

NUMTODSINTERVAL 的文档说它返回一个字符串文字,所以 to_char 没有效果。 上面的这个 hack 只取当前日期/时间(sysdate),截断 HH:mm:ss 组件,然后加回您指定的#seconds,然后将其格式化为仅显示 HH:MM:SS 值

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM