具有固定时间的oracle sql sysdate

c8ib6hqw  于 2021-08-01  发布在  Java
关注(0)|答案(7)|浏览(282)


我有以下疑问-

update esp_notification set start_date_time = TO_DATE('06-25-2020 12:15', 'MM/DD/YYYY hh24:mi') where serial_number ='AUTOSMOK0489' and status = 'active';

例如-
2020年6月24日系统日期,12:15-系统时间。上面提到的数值只是个例子,我总是在第一次运行时选择当前系统日期和当前系统时间。第二、第三、第四。。。。。运行日期应减少1,并且时间必须与第一次运行相同。
我想把我的问题简化一下,因为它看起来很混乱。
在上面的查询中,我想更改今天的日期-1(即06/22/2020),并且每次运行的时间应保持不变,即与之前相同(即04:57)。

Example-
On 1st execution-'06/24/2020 12:15'
On 2nd execution-'06/23/2020 12:15'
On 3rd execution-'06/22/2020 12:15'
On 4th execution-'06/21/2020 12:15'
On 5th execution-'06/20/2020 12:15'
On 6th execution-'06/19/2020 12:15'
On 7th execution-'06/18/2020 12:15'

在查询执行之后,它只更新一行。如何修改sql查询来实现这一点?

I tried to execute the query like-
update esp_notification set start_date_time = TO_DATE(start_date_time-1, 'YYYY-MM-DD hh:mi') where serial_number ='AUTOSMOK7879' and status = 'active';

但此查询随机更新“start\u date\u time”列值,而不设置date-1值。db具有'2020-07-01 03:43:30.0'格式的'start\u date\u time'束值。

zqry0prt

zqry0prt1#

你可以减去 row_numbersysdate 具体如下:

UPDATE ESP
   SET
    START_DATE_TIME = (
        SELECT SYSDATE + 1 - ROW_NUMBER() OVER(
             ORDER BY YOUR_PRIMARY_KEY
        )
          FROM ESP
         WHERE SERIAL_NUMBER = 'OK0489'
           AND STATUS = 'active'
    )
 WHERE SERIAL_NUMBER = 'OK0489'
   AND STATUS = 'active';
kx5bkwkv

kx5bkwkv2#

select trunc(sysdate + rownum) + interval '4' hour + interval '57' minute as dt
from dual 
connect by level <= 10;
cwtwac6a

cwtwac6a3#

请使用下面的查询 update esp SET to_date((to_char(SYSDATE,'MM/DD/YYYY')||' 04:57'),'MM/DD/YYYY hh24:mi') where serial_number ='OK0489' and status = 'active';

vngu2lb8

vngu2lb84#

使用connect by获取行的范围,然后使用间隔算法:

SELECT TRUNC(SYSDATE) - LEVEL + INTERVAL '01 4:57' DAY TO MINUTE AS DT
  FROM DUAL 
  CONNECT BY LEVEL <= 7

db<>在这里摆弄

k97glaaz

k97glaaz5#

你可以用 rownum 正如tejash已经描述过的,但可能是更随机的方式:

update
    (select start_date_time, sysdate - rownum as new_time
    from esp_set
    where serial_number ='OK0489' and status = 'active')
set start_date_time = new_time;

这将选择所需的数据(内部选择)并更新 start_date_time 系统日期每向下一行减少1。另外,只需执行select语句就可以看到操作的结果。
编辑:在注解之后,我想多次更新一行(通过多次执行语句)。我附上了有关数据库表的图像文件以供参考
首次运行:

update esp_notification set start_date_time = TO_DATE('06-25-2020 12:15', 'MM/DD/YYYY hh24:mi') where serial_number ='AUTOSMOK0489' and status = 'active';

以下所有运行:

update esp_notification set start_date_time = start_date_time - 1 where serial_number ='AUTOSMOK0489' and status = 'active';

或者,如果你真的想用一句话来表达:

create table chriz_tab
(
    dat date,
    id number(1)
);
insert into chriz_tab values (sysdate, 1);
insert into chriz_tab values (to_date('01.02.2015 09:10')/*some random date*/, 2);

update chriz_tab 
set dat = case
            when TO_CHAR(dat,'HH24')*60 + TO_CHAR(dat,'MI') >= TO_CHAR(SYSDATE,'HH24')*60 + TO_CHAR(SYSDATE,'MI') - 5/*<-how many minutes this should work before setting sysdate again*//60
            then
                dat - 1
            else
                sysdate
            end
where id = 1;
/
select chriz_Tab.*
from chriz_tab; -> i.e. 01.07.20 13:56:02, 30.06.20 13:56:02, 29.06.20 13:56:02....

对你来说,这可以解释为

update esp_notification 
set start_date_time = case
            when TO_CHAR(start_date_time,'HH24')*60 + TO_CHAR(start_date_time,'MI') >= TO_CHAR(SYSDATE,'HH24')*60 + TO_CHAR(SYSDATE,'MI') - 5/*<-how many minutes this should work before setting sysdate again*//60
            then
                start_date_time - 1
            else
                sysdate
            end
where serial_number ='AUTOSMOK0489' and status = 'active';
ojsjcaue

ojsjcaue6#

我可以通过下面的查询来解决这个问题,只更新日期而不更新时间。

update esp_notification set start_date_time = 
((select start_date_time-1 from esp_notification where serial_number ='AUTOSMOK7879' and status = 'active')) where serial_number ='AUTOSMOK7879' and status = 'active';
uhry853o

uhry853o7#

假设第一次运行前列值为null,可以使用case表达式来决定是将其设置为当前系统还是减去一天:

update esp_notification
set start_date_time =
  case
    when start_date_time is null then sysdate
    else start_date_time - 1
  end
where serial_number ='AUTOSMOK0489' and status = 'active';

db<>在更新之间摆弄短暂的停顿,只是为了证明原始的时间部分被保留下来。
如果该列在第一次运行之前不为null,那么您需要一些其他方法来确定更新是否为“第一次”—例如,可能来自您将作为同一语句的一部分更新的其他列;但我们只能猜测。
我可以通过下面的查询来解决这个问题,只更新日期而不更新时间。

update esp_notification set start_date_time = 
((select start_date_time-1 from esp_notification where serial_number ='AUTOSMOK7879' and status = 'active')) where serial_number ='AUTOSMOK7879' and status = 'active';

您不需要子查询;您可以使用上面我的查询的简化版本:

update esp_notification
set start_date_time = start_date_time - 1
where serial_number ='AUTOSMOK0489' and status = 'active';

但这不能满足你的“第一次跑步”要求。。。
在这两种情况下,都使用datetime/interval。如果您有一个日期值并加上或减去一个数字,则该数字表示整个或部分天数;所以减1等于一天,加0.25等于6小时。
如果你有一个时间戳,那么加/减一个数字会先隐式地将时间戳转换成一个日期,丢失小数秒和时区信息(如果有的话)。根据您对它所做的操作,它可能会隐式地转换回时间戳,甚至是带有时区的时间戳,这将获取会话时区。这可能会给你留下一个明显不同于你开始的价值观。
对于时间戳,您应该使用一个间隔,并且您也可以对日期使用该间隔,您可以将更新更改为:

update esp_notification
set start_date_time = start_date_time - interval '1' day
where serial_number ='AUTOSMOK0489' and status = 'active';

包括这两种情况。

相关问题