从查询访问的 Java 函数比 SQL 函数要多得多,所以我不完全确定你的意思。您不能使用查询声明函数,因为您将混合 SQL 和 PL/SQL 上下文。
您的转换看起来不必要地复杂;你可以这样做:
substr(numtodsinterval(date_difference, 'DAY'), 12, 5)
该numtodsinterval
函数获取您的日期差异并将其转换为间隔数据类型,并substr
获取涵盖小时和分钟的部分。
但它的行为略有不同,因为它会截断而不是四舍五入:
with tmp as (
select to_date('2013-04-11 13:17:15', 'YYYY-MM-DD HH24:MI:SS')
- to_date('2013-04-11 12:57:38', 'YYYY-MM-DD HH24:MI:SS')
as date_difference
from dual
union all
select to_date('2013-04-11 11:11:35', 'YYYY-MM-DD HH24:MI:SS')
- to_date('2013-04-10 22:40:45', 'YYYY-MM-DD HH24:MI:SS')
from dual
union all
select to_date('2013-04-11 00:59:59', 'YYYY-MM-DD HH24:MI:SS')
- to_date('2013-04-11 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
from dual
)
select LTRIM(TO_CHAR(TRUNC((DATE_DIFFERENCE) * 24),'00')) || ':' ||
LTRIM(TO_CHAR(MOD(ROUND((DATE_DIFFERENCE)*24*60),60),'00')),
substr(numtodsinterval(date_difference, 'DAY'), 12, 5)
from tmp;
LTRIM(T SUBSTR(NUMTODSINTERV
------- --------------------
00:20 00:19
12:31 12:30
00:00 00:59
这些的完整间隔是:
NUMTODSINTERVAL(DATE_DIFFERENCE,'DAY')
---------------------------------------------------------------------------
+000000000 00:19:37.000000000
+000000000 12:30:50.000000000
+000000000 00:59:59.000000000
所以很明显第一个会四舍五入到00:20
,但截断到00:19
。正如 Egor Skriptunoff 在评论中指出的那样,您对第三个的计算给出了错误的答案,这就是我现在将其包括在内的原因。
这将四舍五入,但会更长一些:
to_char(round(date '2001-01-01' + date_difference, 'MI'), 'HH24:MI')
我用过的文字中使用的实际日期date '2001-01-01'
无关紧要,它可以是任何一天,trunc(sysdate)
例如,您可以使用它。它只允许您将差异转换回一个DATE
对象,然后您可以在其上使用内置round(date)
函数。为了比较:
with tmp as (...)
select LTRIM(TO_CHAR(TRUNC((DATE_DIFFERENCE) * 24),'00')) || ':' ||
LTRIM(TO_CHAR(MOD(ROUND((DATE_DIFFERENCE)*24*60),60),'00')),
substr(numtodsinterval(date_difference, 'DAY'), 12, 5),
to_char(trunc(date '2001-01-01' + date_difference, 'MI'), 'HH24:MI'),
to_char(round(date '2001-01-01' + date_difference, 'MI'), 'HH24:MI')
from tmp;
LTRIM(T SUBSTR(NUMTODSINTERV TO_CH TO_CH
------- -------------------- ----- -----
00:20 00:19 00:19 00:20
12:31 12:30 12:30 12:31
00:00 00:59 00:59 01:00
这些实际上都没有给你你想要的东西,一个嵌入式的临时功能,但至少如果逻辑更清晰,那么重用它可能就不那么担心了。不过,将其包装在 SQL 函数中可能仍然不是一个糟糕的选择。