• oracle---一表向另一表循环插入数据过程中、发现异常并抛进日志表、直至数据传输完成


    •                            希望本篇文章对您有所帮助
      
      • 1

    应用场景

    当我们需要将一张表中的数据传输到另外一张表中,可能存在两张表中的约束不一样,例如需要将A表中name 字段插入进 B 表中,但是A表中对该name字段并没有做要求,而B表中则规定name 字段不能为null;这就使得在插入的过程中就必须要判断该字段是否为null,如果为null,则该条数据不允许插入,并将该条数据插入进日志表中,这只是其中的一种情况,那么如果像这种判断一旦多了之后,那么编写的代码量就变得很大了。

    解决手段

    动态SQL + 游标 + oracle 异常机制 + 存储过程

    案例

    1. 创建两张表数据交换表
      在这里插入图片描述

    在这里插入图片描述
    即 B 表中ID 是主键,并且 ID、NAME 不能为null;

    1. 创建日志表
      在这里插入图片描述

    2. 为A_TEST 添加数据
      在这里插入图片描述

    分析:

    序列号为1 的数据可以插入进 B_TEST 表中
    序列号为2 的数据不可以插入进 B_TEST 表中,因为该age 是NULL
    序列号为3 的数据不可以插入进 B_TEST 表中,因为该id 是已存在,出现主键冲突
    序列号为4 的数据可以插入进 B_TEST 表中

    实现:

    declare
    v_sql clob;
    v_sql2 clob;
    error_codes number;
    error_msg clob;
    TYPE ref_cursor_type IS REF CURSOR;
    v_serial_nums ref_cursor_type;
    v_serial_num number;
    begin
    
    	v_sql := 'select serial_num from A_TEST';
    	open v_serial_nums for v_sql;
    	loop 
    		fetch v_serial_nums into v_serial_num;
        exit when v_serial_nums%notfound;
                    begin
                    v_sql2 :='insert into B_TEST(id,name,age,address) select id,name,age,address from A_TEST where serial_num='||v_serial_num;
                    execute immediate v_sql2;
    								
    								
    								--此处异常处理
    								exception when others then
                                  error_codes := sqlcode;
    	                            error_msg := sqlerrm;
                                  insert into LOG_TEST(serial_num,error_codes,error_msg) values(v_serial_num,error_codes,error_msg);
                    commit; 
    								end;
    	end loop;
    end;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    在这里插入图片描述
    在这里插入图片描述
    结果与我们分析的一致:
    序列号为1 的数据可以插入进 B_TEST 表中
    序列号为2 的数据不可以插入进 B_TEST 表中,因为该age 是NULL
    序列号为3 的数据不可以插入进 B_TEST 表中,因为该id 是已存在,出现主键冲突
    序列号为4 的数据可以插入进 B_TEST 表中

    总结

    可以看出,根据动态SQL+游标+oracl 自带异常处理机制,可以完成相应的业务需求,但是使用这种方式执行大量数据时,会产生性能问题
    脚本代码只作为一个模块Demo仅供参考,具体根据自己的业务要求进行相应的更改

  • 相关阅读:
    【Linux基础】3.5 动态监控系统,rpm包,yum
    C++前缀和算法的应用:装包裹的最小浪费空间 原理源码测试用例
    RK3568开发板SG90 舵机模块的功能实现-迅为电子
    【Unity Shader​】 屏幕后处理5.0:讨论双重模糊的Bloom
    String Boot项目加密混淆组件xjar+allatori组合使用
    python自动爬取,保存并运行程序。
    JAVA练习题38:正则表达式基本练习
    408王道数据结构强化——应用题
    《机器学习实战》11.Apriori算法进行关联分析
    CNN——卷积神经网络
  • 原文地址:https://blog.csdn.net/m0_56981185/article/details/126024264