oracle 如何将VARCHAR2转换为INTERVAL

k10s72fa  于 2022-11-22  发布在  Oracle
关注(0)|答案(2)|浏览(272)

我想将VARCHAR 2值(如“-28:15:00”)转换为INTERVAL。
如果是常值,则会执行下列动作:

select interval '-09:11:36' hour to second from dual;

但是,这并不(ORA-00923:在预期位置未找到FROM关键字):

select interval MY_VARCHAR hour to second from MY_TABLE;
--comparable to select interval to_char(sysdate, 'hh:mm:ss') hour to second from dual;

我的假设是,当MY_VARCHAR中的显式varchar-value(或分别为to_char中的char)在“interval”和“hour”之间无效时,文字值被隐式转换。
像这样的CAST不起作用(ORA-00963:不支持间隔类型):

select cast(MY_VARCHAR as interval hour to second) from MY_TABLE;
--comparable to select cast('09:11:36' as interval hour to second) from dual;

有效的方法是将'0 '连接为day-value,并将其转换为INTERVAL DAY TO SECOND:

select cast('0 ' || '09:11:36' as interval day to second) from dual;

但是,这只适用于正值,并且只要小时的值小于24。是否有比使用CASE、SUBSTR等解析VARCHAR值更好的解决方案?

inb24sb2

inb24sb21#

您 需要 在 天数 前 加上 减号 , 以 将 其 转换 为 间隔 :

SELECT value,
       CAST( REGEXP_REPLACE(value, '^(-)?', '\10 ') AS INTERVAL DAY TO SECOND )
         AS interval_value
FROM   table_name

中 的 每 一 个
或者 , 使用 简单 的 字符 串 函数 , 输入 的 内容 稍微 多 一些 , 但 可能 更 有效 ( 因为 正则 表达式 很 慢 ) :

SELECT value,
       CAST(
         CASE
         WHEN value LIKE '-%'
         THEN '-0 ' || SUBSTR(value, 2)
         ELSE '0 ' || value
         END
         AS INTERVAL DAY TO SECOND
       ) AS interval_value
FROM   table_name

格式
其中 , 对于 示例 数据 :

CREATE TABLE table_name (value) AS
  SELECT '-09:11:36' FROM DUAL UNION ALL
  SELECT '09:11:36' FROM DUAL;

格式
两者 输出 :
| 价值|间隔 值|
| - -| - -|
| -09 :11 :36| - 00 09 : 11 : 36.000000 ( 中文 )|
| 上午 9 时 11 分 36 秒|09 时 11 分 36 秒|
fiddle 的 最 大 值

mwkjh3gx

mwkjh3gx2#

另 一 种 接受 大于 23 的 小时 值 的 方法 是 将 字符 串 强制 转换 为 ISO 格式 并 使用 the to_dsinterval() function

select my_varchar,
  to_dsinterval(
    regexp_replace(my_varchar, '(-?)(\d+):(\d+):(\d+)', '\1PT\2H\3M\4S')
  ) as interval_value
from my_table

中 的 每 一 个
| 我 的 变量 字符|间隔 值|
| - -| - -|
| -09 :11 :36| 09 时 11 分 36 秒|
| 上午 9 时 11 分 36 秒|09 时 11 分 36 秒|
| 28 时 15 分 02 秒|00000001 04 时 15 分|
| - 28 点 15 分 02 秒|- - - - - - - - - - - - - - -|
fiddle 格式
您 可以 使用 字符 串 函数 来 重新 格式化 字符 串 , 正如@MTO 提到 的 那样 , 对于 大量 数据 来说 , 这样 做 会 更 快 , 但 会 有点 混乱 :

select my_varchar,
  to_dsinterval(
    case
      when substr(my_varchar, 1, 1) = '-'
      then '-PT' || substr(my_varchar, 2, instr(my_varchar, ':', 1, 1) - 2)
      else 'PT' || substr(my_varchar, 1, instr(my_varchar, ':', 1, 1) - 1)
    end || 'H'
    || substr(my_varchar, instr(my_varchar, ':', 1, 1) + 1,
      instr(my_varchar, ':', 1, 2) - instr(my_varchar, ':', 1, 1) - 1) || 'M'
    || substr(my_varchar, instr(my_varchar, ':', 1, 2) + 1) || 'S'
  ) as interval_value
from my_table

格式
| 我 的 变量 字符|间隔 值|
| - -| - -|
| -09 :11 :36| 09 时 11 分 36 秒|
| 上午 9 时 11 分 36 秒|09 时 11 分 36 秒|
| 28 时 15 分 02 秒|00000001 04 时 15 分|
| - 28 点 15 分 02 秒|- - - - - - - - - - - - - - -|
fiddle 格式
如 文档 中 所 示 , 区间 文字 ( 就 像 所有 文字 一样 , 顾名思义 ) 需要 一 个 固定 值 , 而 不是 表达式 或 列 ;在 铁路 图 中 引用 不是 可选 的 :

... 因此 , 您 的 第 一 个 查询 将 获得 ORA - 00923 。
cast() 函数 只 支持 某些 转换 :
注 1 : 日期 时间/间隔 包括 日期 、 时间 戳 、 带 时区 的 时间 戳 、 带 本地 时区 的 时间 戳 、 间隔 日 到 秒 和 间隔 年 到 月 。
所以 您 不能 执行 cast(... as interval hour to second) , 这 将 引发 ORA - 00963 。

相关问题