
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只對數據庫游標有提示作用,真正有