Oracle INCREMENT 时间戳的小数部分

Oracle INCREMENT fractional parts of a timestamp

我有一个 table,其中包含一个时间戳。我希望每行间隔一个 INTERVAL。在下面的示例中,我使用了 15 分钟的间隔

除了时间戳的小数部分始终为 .000000 之外,我的第一个解决方案似乎运行良好,这是我期望但不想要的。我希望它包含一些其他数字。

在我的第二次尝试中,我试图将时间戳的小数部分增加 .100000 这个解决方案的问题是如果我在我的示例中创建许多行 (1344),时间戳的秒部分插入 10 行后增加 1 秒。请参阅下面的第二个解决方案。我也不想这样。

第三,我认为 regexp_replace 解决方案可能会起作用,我可以砍掉第二个解决方案的整数部分(保留小数部分),然后将其添加到我的间隔中。该尝试因错误而失败。请参阅下面的第三次尝试。

有什么方法可以让它发挥作用吗?我可以在不影响日期的 MMDDYYYY HH24:MI:SS 部分的情况下更改时间戳的小数部分。

下面是我的代码和尝试以及我希望生成的示例输出示例。

尝试 #1 小数部分总是 .000000


CREATE TABLE t3 (
seq_num NUMBER  GENERATED BY DEFAULT AS IDENTITY (START WITH 1) NOT NULL,
dt TIMESTAMP  );
/

INSERT into t3 (dt)
with dt (dt, interv) as (
select timestamp '2022-01-01 00:00:00', 
numtodsinterval(15,'MINUTE') from dual
union all
select dt.dt + interv, interv from dt
where dt.dt + interv < date '2022-01-15')
select dt from dt;
/

SELECT * FROM T3 ORDER BY SEQ_NUM 

SEQ_NUM    DT
1    01-JAN-22 12.00.00.000000 AM
2    01-JAN-22 12.15.00.000000 AM
3    01-JAN-22 12.30.00.000000 AM
4    01-JAN-22 12.45.00.000000 AM
5    01-JAN-22 01.00.00.000000 AM
6    01-JAN-22 01.15.00.000000 AM
…
...
1342    14-JAN-22 11.15.00.000000 PM
1343    14-JAN-22 11.30.00.000000 PM
1344    14-JAN-22 11.45.00.000000 PM

尝试 #2 注意秒数在 seq_num 1355 处发生变化。它从 :00 变为 :01


TRUNCATE TABLE T3;
/

INSERT into t3 (dt)
with dt (dt, interv) as (
select timestamp '2022-01-01 00:00:00', 
numtodsinterval(15,'MINUTE') +  
numtodsinterval(  (rownum * .100000), 'SECOND')  from dual
union all
select dt.dt + interv, interv from dt
where dt.dt + interv < date '2022-01-15')
select dt from dt;
/

SELECT * FROM T3 ORDER BY SEQ_NUM 

SEQ_NUM    DT
1345    01-JAN-22 12.00.00.000000 AM
1346    01-JAN-22 12.15.00.100000 AM
1347    01-JAN-22 12.30.00.200000 AM
1348    01-JAN-22 12.45.00.300000 AM
1349    01-JAN-22 01.00.00.400000 AM
1350    01-JAN-22 01.15.00.500000 AM
1351    01-JAN-22 01.30.00.600000 AM
1352    01-JAN-22 01.45.00.700000 AM
1353    01-JAN-22 02.00.00.800000 AM
1354    01-JAN-22 02.15.00.900000 AM
1355    01-JAN-22 02.30.01.000000 AM
1356    01-JAN-22 02.45.01.100000 AM
…
…

第 3 次尝试失败


TRUNCATE TABLE T3;
/

INSERT into t3 (dt)
with dt (dt, interv) as (
select timestamp '2022-01-01 00:00:00', 
numtodsinterval(15,'MINUTE') +  
regexp_replace(
numtodsinterval(  (rownum * .100000), 'SECOND'), '[^.]+\.(.*)$', '0.') from dual
union all
select dt.dt + interv, interv from dt
where dt.dt + interv < date '2022-01-15')
select dt from dt;
/

ORA-30081: invalid data type for datetime/interval arith

期望的输出


SEQ_NUM    DT
1345    01-JAN-22 12.00.00.000000 AM
1346    01-JAN-22 12.15.00.100000 AM
1347    01-JAN-22 12.30.00.200000 AM
1348    01-JAN-22 12.45.00.300000 AM
1349    01-JAN-22 01.00.00.400000 AM
1350    01-JAN-22 01.15.00.500000 AM
1351    01-JAN-22 01.30.00.600000 AM
1352    01-JAN-22 01.45.00.700000 AM
1353    01-JAN-22 02.00.00.800000 AM
1354    01-JAN-22 02.15.00.900000 AM
1355    01-JAN-22 02.30.00.000000 AM
1356    01-JAN-22 02.45.00.100000 AM
1357    01-JAN-22 03.00.00.200000 AM
…
…

看来您只想添加一个 15 分 0.1 秒的间隔

select level seq_num,
       timestamp '2022-01-01 00:00:00' + 
          (level-1) * interval '15' minute +
          (level-1) * interval '0.1' second dt
  from dual
connect by level <= 10

这里 a dbfiddle 显示它生成了您想要的输出。

您可以使用:

INSERT into t3 (dt)
SELECT TIMESTAMP '2022-01-01 00:00:00'
         + (LEVEL - 1) * INTERVAL '15' MINUTE
         + MOD(LEVEL - 1, 10) * INTERVAL '0.1' SECOND
FROM   DUAL
CONNECT BY
       TIMESTAMP '2022-01-01 00:00:00'
         + (LEVEL - 1) * INTERVAL '15' MINUTE
         + MOD(LEVEL - 1, 10) * INTERVAL '0.1' SECOND < DATE '2022-01-15';

或:

INSERT into t3 (dt)
SELECT TIMESTAMP '2022-01-01 00:00:00'
        + NUMTODSINTERVAL((LEVEL-1)*15*60 + MOD(LEVEL-1, 10)/10, 'SECOND')
FROM   DUAL
CONNECT BY
      TIMESTAMP '2022-01-01 00:00:00'
        + NUMTODSINTERVAL((LEVEL-1)*15*60 + MOD(LEVEL-1, 10)/10, 'SECOND')
        < DATE '2022-01-15';

两者都给出了值:

SEQ_NUM DT
1 2022-01-01 00:00:00.000000
2 2022-01-01 00:15:00.100000
3 2022-01-01 00:30:00.200000
4 2022-01-01 00:45:00.300000
5 2022-01-01 01:00:00.400000
6 2022-01-01 01:15:00.500000
7 2022-01-01 01:30:00.600000
8 2022-01-01 01:45:00.700000
9 2022-01-01 02:00:00.800000
10 2022-01-01 02:15:00.900000
11 2022-01-01 02:30:00.000000

db<>fiddle here