PLSQL动态验证包改造:支持批量执行多组业务校验规则
改造PLSQL存储过程实现分组批量校验
1. 需求梳理
- 现有存储过程
pkg_dyn_validation_1.pr_run_field_val仅支持单校验执行 - 需要扩展为按指定组(如A组)批量执行该组下所有校验
- 返回每个校验的执行状态(成功/失败)及对应错误提示
2. 改造方案
2.1 定义输出结果类型
首先在包规范中自定义记录类型和集合类型,用于存储批量校验的结果:
CREATE OR REPLACE PACKAGE pkg_dyn_validation_1 IS -- 单条校验结果记录 TYPE t_validation_result IS RECORD ( rule_id VARCHAR2(50), rule_group VARCHAR2(20), status VARCHAR2(10), -- 'SUCCESS'/'FAILURE' error_message VARCHAR2(2000) ); -- 校验结果集合 TYPE t_validation_result_set IS TABLE OF t_validation_result; -- 保留原有单校验存储过程(兼容历史调用) PROCEDURE pr_run_field_val( p_rule_id IN VARCHAR2, p_result OUT t_validation_result ); -- 新增分组批量校验存储过程 PROCEDURE pr_run_group_val( p_rule_group IN VARCHAR2, p_result_set OUT t_validation_result_set ); END pkg_dyn_validation_1; /
2.2 实现分组校验逻辑
在包体中实现新增的分组校验过程,核心是批量获取指定组的规则,循环调用原有单校验逻辑:
CREATE OR REPLACE PACKAGE BODY pkg_dyn_validation_1 IS -- 原有单校验过程实现(假设逻辑不变,此处仅示意) PROCEDURE pr_run_field_val( p_rule_id IN VARCHAR2, p_result OUT t_validation_result ) IS v_rule_rec YOUR_RULE_TABLE%ROWTYPE; -- 替换为实际规则表名 BEGIN -- 原有校验逻辑:查询规则、执行校验、赋值结果 SELECT * INTO v_rule_rec FROM YOUR_RULE_TABLE WHERE rule_id = p_rule_id; -- 此处省略具体校验执行逻辑,根据规则执行后设置状态 p_result.rule_id := p_rule_id; p_result.rule_group := v_rule_rec.rule_group; p_result.status := 'SUCCESS'; p_result.error_message := NULL; EXCEPTION WHEN OTHERS THEN p_result.status := 'FAILURE'; p_result.error_message := SQLERRM; END pr_run_field_val; -- 分组批量校验过程实现 PROCEDURE pr_run_group_val( p_rule_group IN VARCHAR2, p_result_set OUT t_validation_result_set ) IS v_rule_ids SYS.ODCIVARCHAR2LIST; v_result t_validation_result; BEGIN -- 1. 批量获取指定组的所有规则ID SELECT rule_id BULK COLLECT INTO v_rule_ids FROM YOUR_RULE_TABLE WHERE rule_group = p_rule_group; -- 2. 初始化结果集合 p_result_set := t_validation_result_set(); p_result_set.EXTEND(v_rule_ids.COUNT); -- 3. 循环执行每个规则的校验 FOR i IN 1..v_rule_ids.COUNT LOOP pr_run_field_val(v_rule_ids(i), v_result); p_result_set(i) := v_result; END LOOP; EXCEPTION WHEN NO_DATA_FOUND THEN p_result_set := t_validation_result_set(); -- 无规则时返回空集合 WHEN OTHERS THEN RAISE; -- 可根据业务需求调整全局异常处理逻辑 END pr_run_group_val; END pkg_dyn_validation_1; /
2.3 调用示例
DECLARE v_results pkg_dyn_validation_1.t_validation_result_set; BEGIN -- 执行A组的所有校验 pkg_dyn_validation_1.pr_run_group_val('A', v_results); -- 遍历输出每个校验的结果 FOR i IN 1..v_results.COUNT LOOP DBMS_OUTPUT.PUT_LINE('规则ID: ' || v_results(i).rule_id); DBMS_OUTPUT.PUT_LINE('所属组: ' || v_results(i).rule_group); DBMS_OUTPUT.PUT_LINE('执行状态: ' || v_results(i).status); DBMS_OUTPUT.PUT_LINE('错误提示: ' || NVL(v_results(i).error_message, '无')); DBMS_OUTPUT.PUT_LINE('---'); END LOOP; END; /
3. 关键说明
- 保留原
pr_run_field_val保证兼容性,避免影响原有业务调用 - 使用
BULK COLLECT批量获取规则ID,提升查询效率 - 自定义集合类型统一返回所有校验结果,方便调用方逐个处理规则状态
- 单个规则的异常已在原过程中捕获,不影响其他规则执行;全局异常可根据业务需求调整处理逻辑
内容的提问来源于stack exchange,提问作者Adeel Aslam
相关产品推荐
相关产品推荐

