• 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仅供参考,具体根据自己的业务要求进行相应的更改

  • 相关阅读:
    外包干了9天,技术退步明显。。。。。
    《web课程设计》 基于HTML+CSS+JavaScript实现中国水墨风的小学学校网站模板(6个网页)
    uniapp基础篇 - - 自定义组件
    MobaXterm工具软件使用介绍
    Rust的高效易用日志库—tklog
    Godot 官方2D游戏笔记(1):导入动画资源和添加节点
    【c++刷题Day2】专题2线性DP
    连接数据库报错2003-Can‘t connect to MySQL server on ‘localhost‘(10061)
    JS进阶-编程思想
    数据库系列:MySQL索引优化总结(综合版)
  • 原文地址:https://blog.csdn.net/m0_56981185/article/details/126024264