137、ABAP游标与动态SQL

137、ABAP游标与动态SQL 137、ABAP游标与动态SQL那是在一个夜班运维的凌晨,MES系统的某个报表程序突然报出“OPEN SQL: database error”的短转储。查了ST22,指向一段用SELECT-ENDSELECT循环读取Z表的逻辑,数据量不过两万行,却因为每次循环内还嵌套了三次单条SELECT,把数据库会话拖垮了。那时候我刚接手ABAP,第一反应是加索引、优化WHERE,可DBA说索引已经到位,问题出在游标持有期间反复打开新的隐式游标,加上旧版本ABAP对OPEN CURSOR的锁处理不友好。后来我把那段嵌套的SELECT-ENDSELECT改成显式游标一次抓一批,再用内部表批量处理,数据库压力瞬间降下来。从那天起,我才真正去研究ABAP游标的底层行为,也顺带把动态SQL的坑踩了个遍。先聊聊游标。ABAP里的SELECT-ENDSELECT其实是隐式游标,系统帮你打开、取值、关闭,看着方便,可每取一行都保持数据库游标打开状态,如果循环体里又去操作别的表,数据库端就会出现游标交叉占用。更隐蔽的是,SELECT-ENDSELECT不适合大数据量,因为每次FETCH都是一次数据库往返,十万行就是十万次网络开销。我见过有人拿它读百级表,硬生生跑了十几分钟,最后被业务投诉。显式游标用OPEN CURSOR加FETCH NEXT CURSOR,可以一次抓多条到内部表。关键参数是PACKAGE SIZE,这个不是ABAP语句里的关键字,而是通过FETCH NEXT CURSOR … INTO … 配合内部表时,系统默认按内部表头大小批量读。其实ABAP里控制批量大小主要靠OPEN CURSOR … PACKAGE SIZE n,但很多人不知道这个n只对数据库游标有提示作用,真正有