• 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网络加固操作
    从零开始学Graph Database:什么是图
    图像处理02 matlab中NSCT的使用
    10.4号作业
    【1024】 1024
    NodeMCU ESP8266开发流程详解(图文并茂)
    数据结构之空间复杂度、顺序表
    消费与储蓄的决定-中国视角下的宏观经济
    C语言链表
    [论文精度|博士论文]非结构环境下病虫害识别方法研究
  • 原文地址:https://blog.csdn.net/m0_56981185/article/details/126024264