如何在SQLRPGLE中通过单条FETCH语句获取多条记录
可行性结论
完全可行。SQLRPGLE原生支持行集(Rowset)模式的FETCH操作,单条FETCH语句即可批量拉取多条记录到宿主数组中,相比传统循环单条FETCH的写法,能大幅减少程序和数据库之间的交互次数,大批量数据处理场景下性能提升非常明显。该特性从IBM i 7.1版本开始就原生支持,目前绝大多数生产环境都满足版本要求,不存在兼容性障碍。
具体实现方法
整个实现逻辑和普通单条FETCH的流程差异不大,核心是把单值宿主变量换成对应维度的数组,FETCH语句增加批量拉取的行数声明即可:
- 第一步:定义批量接收数据的宿主结构数组
按照单次要拉取的最大记录数,定义带DIM关键词的结构数组,同时配套定义结构完全一致的指示符数组,用来处理字段空值场景,另外单独定义变量存储单次FETCH实际返回的记录数。参考自由格式RPG写法:// 定义单次拉取上限为100条的员工数据宿主数组 dcl-ds empDs dim(100) qualified; empId int(10); empName char(30); deptId int(5); salary packed(9:2); end-ds; // 配套指示符数组,维度、字段顺序和宿主数组完全对应 dcl-ds empInd dim(100) qualified; empIdInd int(5); empNameInd int(5); deptIdInd int(5); salaryInd int(5); end-ds; // 存储单次FETCH实际拿到的记录数 dcl-s fetchRtnCnt int(10); dcl-s fetchSize int(10) inz(100); // 可配置的单次拉取条数 dcl-s loopIdx int(10); - 第二步:声明游标并执行批量FETCH
游标声明不需要加特殊语法,和普通游标写法完全一致;FETCH语句增加FOR n ROWS子句指定单次拉取条数,INTO后直接对接之前定义的宿主数组和指示符数组即可。拉取完成后通过GET DIAGNOSTICS拿到本次实际返回的记录数:// 普通游标声明即可,无额外语法要求 exec sql declare cEmp cursor for select empId, empName, deptId, salary from employee where workStatus = 'A' order by empId; exec sql open cEmp; // 单条FETCH语句一次性拉取最多100条记录 exec sql fetch next from cEmp for :fetchSize rows into :empDs :empInd; // 读取本次实际返回的记录数 exec sql get diagnostics :fetchRtnCnt = ROW_COUNT; - 第三步:循环处理数据并拉取后续批次
拿到返回的记录数后,遍历数组对应下标的元素完成业务逻辑即可,本批处理完成后再执行下一次批量FETCH,直到返回记录数为0时关闭游标结束流程:dow fetchRtnCnt > 0; // 仅遍历实际返回的记录数,不要遍历整个数组避免读到残留脏数据 for loopIdx = 1 to fetchRtnCnt; // 先通过指示符判断字段是否为空 if empInd(loopIdx).salaryInd < 0; // 空值字段的业务处理逻辑 endif; // 正常业务逻辑处理,比如计算薪资、生成报表等 dsply ('员工ID:' + %char(empDs(loopIdx).empId) + ' 姓名:' + %trim(empDs(loopIdx).empName)); endfor; // 拉取下一批数据 exec sql fetch next from cEmp for :fetchSize rows into :empDs :empInd; exec sql get diagnostics :fetchRtnCnt = ROW_COUNT; enddo; // 收尾关闭游标 exec sql close cEmp;
常见注意事项
- 单次拉取条数不要设置过大:常规业务场景设置50-500条性价比最高,过大会占用过多作业内存,过小则体现不出批量拉取的性能优势。
- 必须配套指示符数组:只要查询结果的字段存在为空的可能,不携带指示符数组会触发SQL数据映射错误,直接导致程序异常。
- 不要超下标遍历数组:FETCH最后一批数据时大概率凑不满数组维度,必须严格按照实际返回的记录数遍历,否则会读到之前批次残留的脏数据,引发逻辑错误。
- 行集FETCH的游标定位逻辑和单条FETCH完全一致,返回数据的顺序、过滤规则和游标定义完全匹配,不会出现丢记录、跳记录、顺序错乱的问题。
内容的提问来源于stack exchange,提问作者Kunal Roy
相关产品推荐
相关产品推荐

