Oracle:如何使用WHILE循环捕获FORALL SAVE EXCEPTIONS异常
用WHILE循环替代FOR循环遍历SQL%BULK_EXCEPTIONS捕获批量加载错误
以下是可直接运行的PL/SQL代码,通过WHILE循环遍历SQL%BULK_EXCEPTIONS来捕获批量操作中的错误记录:
-- 创建测试表(若已存在则跳过) CREATE TABLE test_bulk_load ( id NUMBER PRIMARY KEY, name VARCHAR2(50) NOT NULL ); DECLARE -- 定义与表结构匹配的集合类型 TYPE t_load_data IS TABLE OF test_bulk_load%ROWTYPE; v_load_data t_load_data := t_load_data(); -- 异常遍历计数器 v_exception_idx NUMBER := 1; BEGIN -- 初始化测试数据,包含重复主键(触发唯一约束错误)和空name(触发非空约束错误) v_load_data.EXTEND(4); v_load_data(1).id := 1; v_load_data(1).name := 'Valid Record 1'; v_load_data(2).id := 1; -- 重复主键,会报错 v_load_data(2).name := 'Duplicate ID'; v_load_data(3).id := 3; v_load_data(3).name := NULL; -- 空name,会报错 v_load_data(4).id := 4; v_load_data(4).name := 'Valid Record 2'; -- 批量插入,启用SAVE EXCEPTIONS捕获错误 FORALL i IN v_load_data.FIRST..v_load_data.LAST SAVE EXCEPTIONS INSERT INTO test_bulk_load VALUES v_load_data(i); COMMIT; DBMS_OUTPUT.PUT_LINE('批量插入完成,无错误'); EXCEPTION WHEN OTHERS THEN -- 用WHILE循环遍历所有捕获到的异常 WHILE v_exception_idx <= SQL%BULK_EXCEPTIONS.COUNT LOOP -- 获取错误对应的原集合索引、错误码和错误信息 DBMS_OUTPUT.PUT_LINE('错误序号: ' || v_exception_idx); DBMS_OUTPUT.PUT_LINE('原数据索引: ' || SQL%BULK_EXCEPTIONS(v_exception_idx).ERROR_INDEX); DBMS_OUTPUT.PUT_LINE('Oracle错误码: ' || SQL%BULK_EXCEPTIONS(v_exception_idx).ERROR_CODE); DBMS_OUTPUT.PUT_LINE('错误信息: ' || SQLERRM(-SQL%BULK_EXCEPTIONS(v_exception_idx).ERROR_CODE)); DBMS_OUTPUT.PUT_LINE('--------------------------'); -- 计数器自增,进入下一个异常 v_exception_idx := v_exception_idx + 1; END LOOP; -- 回滚未提交的有效数据(可选,根据业务需求调整) ROLLBACK; END; /
关键说明:
SQL%BULK_EXCEPTIONS是一个关联数组,索引从1开始,COUNT属性记录捕获到的异常总数- 初始化计数器
v_exception_idx为1,循环条件设置为v_exception_idx <= SQL%BULK_EXCEPTIONS.COUNT,确保遍历所有异常 - 每次循环中,通过
SQL%BULK_EXCEPTIONS(v_exception_idx).ERROR_INDEX获取出错数据在原集合中的位置,ERROR_CODE获取Oracle错误码 - 使用
SQLERRM(-错误码)可以将错误码转换为可读的错误信息(注意需要加负号)
内容的提问来源于stack exchange,提问作者Narasimhan M
相关产品推荐
相关产品推荐

