问题描述
如何创建一个过程来验证表的每一行并根据已建立的语句更新字段? 我有4个合作领域
-
SYS_UPDATE_PING
-
UPDATE_PING
-
PING_STATUS
-
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;
它的工作方式应该比逐行处理更快。