查询从oracle 11g中的systimestamp中减去日期

时间:2016-10-17 05:59:32

标签: sql oracle oracle11g date-arithmetic

我想对从另一个查询返回的日期和oracle SQL中的系统时间执行减法操作。到目前为止,我已经能够使用另一个查询的结果,但是当我尝试从systimestamp中减去时,它会给我以下错误

  

ORA-01722:无效的号码
  “01722。 00000 - “无效号码”
  *原因:指定的号码无效   *操作:指定有效数字。

以下是我的查询

<dependencies>
    <dependency>
        <groupId>foo</groupId>
        <artifactId>bar</artifactId>
        <exclusions>
            <!-- this exclusion is just for the child -->
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

我也试过这个

select round(to_number(systimestamp - e.last_time) * 24) as lag 
from (
   select ATTR_VALUE as last_time 
   from CONFIG 
   where ATTR_NAME='last_time' 
   and PROCESS_TYPE='new'
)  e;

我希望时间间隔之间的差异以小时为单位。

感谢您提前提供任何帮助。

P.S。 ATTR_VALUE的数据类型是VARCHAR2(150)。 select to_char(sys_extract_utc(systimestamp)-e.last_time,'YYYY-MM-DD HH24:MI:SS') as lag from ( select ATTR_VALUE as last_time from CONFIG where ATTR_NAME='last_time' and PROCESS_TYPE='new' ) e; 的示例结果为e.last_time

2 个答案:

答案 0 :(得分:1)

  

“它的VARCHAR2(150)。这意味着我需要将其转换为日期”

ATTR_VALUE是一个字符串,所以是的,您需要在尝试将其与另一个数据类型进行比较之前将其转换为正确的类型。给定样本数据,正确的类型是时间戳,在这种情况下,子查询应为:

(
   select to_timestamp(ATTR_VALUE, 'yyyy-mm-dd hh24:mi:ss.ff5') as last_time 
   from CONFIG 
   where ATTR_NAME='last_time' 
     and PROCESS_TYPE='new'
)  

假设您的样本代表CONFIG表中给定键的所有值。如果您有不同格式的值,您的查询将以其他方式中断:这是使用此方法的危险。

答案 1 :(得分:0)

所以经过大量的试验和错误后,我得到了这个

1。最初判定错误的原因是e.last_time的data_type为VARCHAR(150)。    要查找我使用的表中给定列的数据类型

desc <table_name>

在我的案例中是desc CONFIG

2. 要将VARCHAR转换为系统时间,我有两个选项to_timestampto_date。如果我使用to_timestamp喜欢

select round((systimestamp - to_timestamp(e.last_time,'YYYY-MM-DD HH24:MI:SSSSS')) * 24, 2) as lag 
from (
   select ATTR_VALUE as last_time 
   from CONFIG 
   where ATTR_NAME='last_time' 
   and PROCESS_TYPE='new'
)  e;

由于日期差异与NUMBER相似,我得到了一轮预期INTERVAL DAY TO SECONDS并获得+41 13:55:20.663990的错误。要将其转换为小时,需要一个复杂的逻辑。

另一种方法是使用我喜欢的to_data并将其用作

select round((sysdate - to_date(e.last_time,'YYYY-MM-DD HH24:MI:SSSSS')) * 24, 2) as lag 
from (
   select ATTR_VALUE as last_time 
   from CONFIG 
   where ATTR_NAME='last_time' 
   and PROCESS_TYPE='new'
)  e;

这会返回所需的结果,即小时差异四舍五入为2个浮动数字