Oracle存储过程里的Update疑似失效的原因

Update操作在存储过程里的那些事

    • 问题描述
    • 问题模拟

开发环境:Oracle 11g r2 , pl/sql

问题描述

今天工作中遇到了一个很惊奇的问题,用存储过程更新一个表里的字段时,就是无法正常更新进去。在sql script里手动update后就能正常更新,询问了一个大神,找到了原因–就是用for循环游标一条一条更新,之前的残余数据不会被清除,特此记录下,执行更新前一定要清理历史数据。

问题模拟


--创建表TEST_ZL_1和TEST_ZL_1,TEST_ZL_1插入5条数据,TEST_ZL_2插入6条数据
--TEST_ZL_2第六条模拟历史数据
CREATE TABLE TEST_ZL_1
(
ID NUMBER,
NAME VARCHAR2(20)
);
insert into TEST_ZL_1 values(1,'a');
insert into TEST_ZL_1 values(2,'b');
insert into TEST_ZL_1 values(3,'c');
insert into TEST_ZL_1 values(4,'d');
insert into TEST_ZL_1 values(5,'e');
commit;
CREATE TABLE TEST_ZL_2 as SELECT * FROM TEST_ZL_1 where 1=2;
insert into TEST_ZL_2 values(1,'a');
insert into TEST_ZL_2 values(2,'a');
insert into TEST_ZL_2 values(3,'a');
insert into TEST_ZL_2 values(4,'a');
insert into TEST_ZL_2 values(5,'a');
insert into TEST_ZL_2 values(6,'a');
commit;
--创建存储过程,将TEST_ZL_1根据id号更新进TEST_ZL_2中
CREATE OR REPLACE PROCEDURE PRO_TEST_ZL_2
AS
BEGIN
  FOR AA IN(
    SELECT A.ID,A.NAME FROM TEST_ZL_1 A
    ) LOOP
    UPDATE TEST_ZL_2 B SET B.NAME=AA.NAME WHERE B.ID=AA.ID;
    COMMIT;
  END LOOP;
END PRO_TEST_ZL_2;

--执行存储过程
call pro_test_zl_2();
--查看TEST_ZL_2表
SELECT * FROM test_zl_2;

Oracle存储过程里的Update疑似失效的原因_第1张图片
第六条数据就是历史数据没有被更新,导致更新失败,就是因为之前没清除数据

可以换手工更新进行,首先将表还原回原来数据

create table test_zl_2_bak as
select *
from test_zl_2 as of timestamp to_timestamp('2019-12-05 22:49:00','yyyy-mm-dd hh24:mi:ss');
--时间戳操作查询语句
--select * from V$SQL where SQL_TEXT like '%update test_zl_2%'
delete  test_zl_2 where 1=1;
commit;
insert into test_zl_2  SELECT * FROM test_zl_2_bak;
commit;

此时,test_zl_2表已经恢复到刚开始建表的时候的数据
Oracle存储过程里的Update疑似失效的原因_第2张图片
再在外用update操作

update test_zl_2 b set b.name=(SELECT a.name FROM test_zl_1 a where a.id=b.id);
COMMIT;
SELECT * FROM test_zl_2

Oracle存储过程里的Update疑似失效的原因_第3张图片
也就是说,在外用update更新时,它会根据关联条件(a.id=b.id)进行更新,关联不到的,就赋默认值NULL!!!

你可能感兴趣的:(pl/sql,oracle,Oracle)