我正在尝试使用JDBC连接计算oracle数据库中两个日期之间的差。我遵循this问题的建议,使用的查询如下:
npm i services/access-request
,我收到以下错误消息:
SELECT CREATE_DATE - CLOSED
FROM TRANSACTIONS;
我应该更改什么才能成功计算日期之间的差异?
注意:Incompatible value type specified for
column:CREATE_DATE-CLOSED. Column Type = 11 and Value Type =
8.[10176] Error Code: 10176
和CREATE_DATE
都具有CLOSED
类型
答案 0 :(得分:0)
您找到的答案与date
数据类型有关,但是您正在处理timestamp
s。减去两个Oracle date
会返回一个数字,而减去timestamp
会产生一个interval
数据类型。这可能不是您想要的,显然,您的驱动程序无法正确处理此数据类型。
对于此用例,一种解决方案是在将cast
到timestamp
之前date
至select cast(create_date as date) - cast(closed as date) from transactions;
:
::new()
答案 1 :(得分:0)
如前所述,似乎JDBC无法使用INTERVAL数据类型。用EXTRACT函数将其强制转换为数字的预期输出怎么样?如果您希望两个时间戳之间的秒数为:
SELECT EXTRACT(SECOND FROM (CREATE_DATE - CLOSED)) FROM TRANSACTIONS;
以下是可以代替SECOND
使用的选项列表:
https://docs.oracle.com/database/121/SQLRF/functions067.htm#SQLRF00639
答案 2 :(得分:0)
当我们从另一个日期减去一个日期时,Oracle将差值作为一个数字给出:这是简单的算术运算。但是,当我们从另一个中减去一个时间戳时(您正在执行的操作),结果是INTERVAL。 DB diagram。
根据您要对结果执行的操作,有两种解决方法。首先是从间隔结果计算秒数。 extract second from ...
仅提供间隔中的秒数。如果您的间隔时间不超过五十九秒,那就很好了。较长的时间间隔要求我们提取分钟,小时甚至几天。这样的解决方案是:
select t.*
, extract (day from (t.closed - t.create_date)) * 84600
+ extract (hour from (t.closed - t.create_date)) * 3600
+ extract (minute from (t.closed - t.create_date)) * 60
+ extract (second from (t.closed - t.create_date)) as no_of_secs
from transactions t
第二种解决方案是遵循JDBC映射指南中的建议并将间隔转换为字符串:
select t.*
, cast ((t.closed - t.create_date) as varchar2(128 char)) as intrvl_str
from transactions t
字符串间隔的格式是冗长的:INTERVAL'+000000001 04:40:59.710000'DAY(9)TO SECOND
。这在应用程序的Java端可能没有用。但是使用正则表达式,我们可以将其转换为可以转换为Older versions of JDBC don't like the INTERVAL datatype (docs):PnDTnHnMn.nS
的字符串。
select t.id
, regexp_replace(cast ((t.closed - t.create_date) as varchar2(128 char))
, 'INTERVAL''\+([0-9]+) ([0-9]{2}):([0-9]{2}):([0-9]{2})\.([0-9]+)''DAY\(9\)TO SECOND'
, 'P\1DT\2H\3M\4.\5S')
as duration
from transactions t