如何更新表Oracle PLSQL中的每一行

问题描述

如何创建一个过程来验证表的每一行并根据已建立的语句更新字段? 我有4个合作领域

  1. SYS_UPDATE_PING
  2. UPDATE_PING
  3. PING_STATUS
  4. TIME_OUT_PING

这是我的代码

create or replace procedure SP_DASHBOARD_PINGSTATUS is
begin
  declare
  sp_ping_final number;
  BEGIN
        Update rsmes.tb_op_pc_monitoring_v4 t
         set t.sys_update_ping = sysdate;
   for c in (select ((SYS_UPDATE_PING - UPDATE_PING)*60*60*24) as PING_RESULT into sp_ping_final from TB_OP_PC_MONITORING_V4)
     loop
       sp_ping_final := c.ping_result;
       if c.ping_result <= 5 then
        Update rsmes.tb_op_pc_monitoring_v4 tg
        set tg.ping_status = 'OK',tg.time_out_ping = sp_ping_final;
       else
        Update rsmes.tb_op_pc_monitoring_v4 tn
        set tn.ping_status = 'NG',tn.time_out_ping = sp_ping_final;
        end if;
       end loop;
        commit;
  END;
end SP_DASHBOARD_PINGSTATUS;

我在SYS_UPDATE_PING和UPDATE_PING之间进行时差,如果以秒为单位的结果小于5,则必须将PING_STATUS字段更新为OK,然后将秒差放入TIME_OUT_PING,否则它将更新NG并将秒差放入TIME_OUT_PING , 我希望它在每一行进行比较,但是它会在所有字段上而不是一个一个地更新我。

我知道我忘记了什么,但是您能帮我找到我的错并知道解决方法吗? 谢谢

解决方法

这是因为UPDATE语句缺少WHERE子句。没有它,您将始终更新表中的所有行。

这意味着游标应该包含某种ID,您将在UPDATE中重用它。例如:

for c in (select id,--> this
                ((sys_update_ping - ...)
         ) loop
  ...
  update tb_op_pc_monitoring_v4 tg set
    tg.ping_status = 'OK'
    where tg.id = c.id;                         --> this
  ...
end loop;

此外,您也不会在光标中SELECT INTO。完全删除sp_ping_final


最后,我想说您根本不需要PL / SQL(尤其是循环)。您编写的整个代码可以重写为一个

UPDATE tb_op_pc_monitoring_v4 tg
   SET tg.ping_status =
          CASE
             WHEN (SYSDATE - tg.update_ping) * 60 * 60 * 24 <= 5 THEN 'OK'
             ELSE 'NG'
          END,tg.time_out_ping = (SYSDATE - tg.update_ping) * 60 * 60 * 24;

它的工作方式应该比逐行处理更快。