Oracle PL/SQL中按公共匹配字段在关联数组间复制字段值的方法
PL/SQL关联数组按匹配字段同步col3值实现方案
针对两个以col1、col2为公共匹配键的关联数组,要把array2的col3值同步到array1对应记录,可根据数据量大小选择以下两种实现方式:
方案1:双层循环匹配(适合千条级以内小数据量场景)
写法最简单,不需要额外定义类型,直接两层遍历匹配即可,匹配到对应记录后直接赋值,提前退出内层循环减少无效计算:
DECLARE -- 原有自定义类型和数组声明(实际业务中如果已经在包/块头部声明过,不需要重复写) TYPE T_ARRAY1_REC IS RECORD(COL1 NUMBER,COL2 NUMBER,COL3 NUMBER,COL4 varchar2(1)); TYPE T_ARRAY1 IS TABLE OF T_ARRAY1_REC INDEX BY BINARY_INTEGER; array1 T_ARRAY1; TYPE T_ARRAY2_REC IS RECORD(COL1 NUMBER,COL2 NUMBER,COL3 NUMBER); TYPE T_ARRAY2 IS TABLE OF T_ARRAY2_REC INDEX BY BINARY_INTEGER; array2 T_ARRAY2; BEGIN -- 此处省略array1、array2的初始数据填充逻辑 -- 同步赋值逻辑 FOR i IN 1..array1.COUNT LOOP FOR j IN 1..array2.COUNT LOOP -- 同时匹配col1、col2两个公共键 IF array1(i).col1 = array2(j).col1 AND array1(i).col2 = array2(j).col2 THEN array1(i).col3 := array2(j).col3; EXIT; -- 匹配到即退出内层循环,避免多余遍历 END IF; END LOOP; END LOOP; END; /
- 优点:代码逻辑直白,零额外学习成本
- 缺点:时间复杂度为O(n*m),两个数组数据量过万后性能下降明显
方案2:复合键映射匹配(适合万条级以上大数据量场景)
先遍历一次array2,把col1、col2拼接成唯一字符串键,将对应col3值存入临时索引映射表,再遍历一次array1直接通过键取值,整体时间复杂度为O(n+m),大数据量下性能远高于双层循环:
DECLARE -- 原有自定义类型和数组声明 TYPE T_ARRAY1_REC IS RECORD(COL1 NUMBER,COL2 NUMBER,COL3 NUMBER,COL4 varchar2(1)); TYPE T_ARRAY1 IS TABLE OF T_ARRAY1_REC INDEX BY BINARY_INTEGER; array1 T_ARRAY1; TYPE T_ARRAY2_REC IS RECORD(COL1 NUMBER,COL2 NUMBER,COL3 NUMBER); TYPE T_ARRAY2 IS TABLE OF T_ARRAY2_REC INDEX BY BINARY_INTEGER; array2 T_ARRAY2; -- 新增:临时映射表类型,键为拼接的复合字符串,值为对应col3 TYPE T_COL3_MAP IS TABLE OF NUMBER INDEX BY VARCHAR2(100); v_col3_map T_COL3_MAP; v_match_key VARCHAR2(100); BEGIN -- 此处省略array1、array2的初始数据填充逻辑 -- 第一步:遍历array2构建键值映射 FOR j IN 1..array2.COUNT LOOP -- 用不会出现在col1、col2值中的特殊字符做分隔符拼接,避免键冲突,比如选| v_match_key := array2(j).col1 || '|' || array2(j).col2; v_col3_map(v_match_key) := array2(j).col3; END LOOP; -- 第二步:遍历array1直接从映射表取值赋值 FOR i IN 1..array1.COUNT LOOP v_match_key := array1(i).col1 || '|' || array1(i).col2; -- 加存在性判断,避免无匹配记录时抛出NO_DATA_FOUND异常 IF v_col3_map.EXISTS(v_match_key) THEN array1(i).col3 := v_col3_map(v_match_key); END IF; END LOOP; END; /
注意事项
- 拼接复合键的分隔符必须保证不会和
col1、col2存储的内容冲突,比如两个字段都是纯数字,用|、#这类特殊字符就不会出现键冲突问题 - 如果业务上能保证
array1的所有记录在array2中都有对应匹配项,可以省略EXISTS判断
两种方案执行完成后,array1的col3都会被正确同步为对应匹配的56、67、89,原有col4的P、T、P值会完整保留,和预期结果完全一致。
内容的提问来源于stack exchange,提问作者user2280352
相关产品推荐
相关产品推荐

