如何在SQLRPGLE中使用CURSOR更新文件数据
SQLRPGLE中使用SQL游标更新数据的方案
核心结论:不存在完全不编写UPDATE语句、仅通过SQL游标本身就能完成数据更新的实现。所有SQL游标相关的更新操作,都需要配合WHERE CURRENT OF语法的定位UPDATE语句完成,这类UPDATE不需要手动写行匹配条件,开发效率很高。
下面是标准实现步骤:
- 声明可更新游标
声明游标时必须添加FOR UPDATE子句,标记该游标支持更新操作,可在OF后指定需要更新的字段,不指定则默认支持更新所有查询返回的字段。注意如果查询语句使用了分组、去重、多表连接、聚合函数等语法,游标会自动变为只读,无法执行更新。
示例代码:
EXEC SQL DECLARE update_emp_cur CURSOR FOR SELECT emp_id, emp_name, salary, dept FROM emp_file WHERE hire_date < '2020-01-01' FOR UPDATE OF salary, dept;- 声明可更新游标
- 定义宿主结构接收游标数据
在RPGLE中定义对应的数据结构,作为FETCH操作的接收宿主变量:
Dcl-DS emp_rec Qualified; emp_id Int(10); emp_name Char(30); salary Packed(10:2); dept Char(15); End-DS;- 定义宿主结构接收游标数据
- 循环读取游标、执行定位更新
打开游标后逐行FETCH数据,完成业务逻辑修改字段值后,执行定位UPDATE,通过WHERE CURRENT OF 游标名直接锁定游标当前指向的行更新,不需要额外写主键匹配条件,不会出现误更新其他行的问题。
示例代码:
// 打开游标 EXEC SQL OPEN update_emp_cur; // 读取第一行 EXEC SQL FETCH NEXT FROM update_emp_cur INTO :emp_rec; // SQLCOD为0代表读取成功 Dow SQLCOD = 0; // 执行业务逻辑:符合条件的员工涨薪12%,归属研发部 emp_rec.salary = emp_rec.salary * 1.12; emp_rec.dept = 'RD'; // 执行定位更新 EXEC SQL UPDATE emp_file SET salary = :emp_rec.salary, dept = :emp_rec.dept WHERE CURRENT OF update_emp_cur; // 读取下一行 EXEC SQL FETCH NEXT FROM update_emp_cur INTO :emp_rec; EndDo; // 操作完成关闭游标 EXEC SQL CLOSE update_emp_cur;- 循环读取游标、执行定位更新
常见误区说明
有部分开发者误以为修改FETCH到宿主变量的值就会自动同步到库表,这个是其他平台的游标特性,在DB2 for i的SQLRPGLE环境下不成立:宿主变量存储在程序本地内存,不执行显式UPDATE的话,所有修改都不会落库。
如果完全不想写UPDATE语句,可以用RPG原生的记录级访问:在F规格表中定义需要更新的物理文件,用READ/CHAIN读取记录后,修改字段值直接执行UPDATE 记录格式名即可,但这是RPG原生文件操作的能力,不属于SQL CURSOR的实现范畴。
内容的提问来源于stack exchange,提问作者Kunal Roy
相关产品推荐
相关产品推荐

