从BKPF表获取最新凭证号的ABAP技术咨询
BKPF表获取最新凭证号的方案对比与优化建议
背景说明
需要从BKPF表中获取最新的凭证号,仅能通过公司代码(BUKRS)和凭证类型(BLART)作为筛选条件。尝试过用日期字段缩小范围,但因日期不连续,这个思路行不通,目前纠结两种实现方案:
方案一:全量筛选后排序取最后一条
先把符合条件的所有数据拉到内表,再排序后读取最后一条记录:
SELECT * INTO TABLE gt_bkpf FROM bkpf WHERE bukrs EQ ls_upload-bukrs AND blart EQ ls_upload-blart. SORT gt_bkpf ASCENDING BY belnr. DESCRIBE TABLE gt_bkpf LINES lv_lastdoc. READ TABLE gt_bkpf INTO gs_bkpf INDEX lv_lastdoc.
方案二:数据库层面直接取最大凭证号
用UP TO 1 ROWS配合ORDER BY DESCENDING,让数据库直接返回最大的凭证号:
SELECT belnr UP TO 1 ROWS INTO lv_belnr FROM bkpf WHERE bukrs EQ ls_upload-bukrs AND blart EQ ls_upload-blart ORDER BY belnr DESCENDING. ENDSELECT.
性能对比
方案二的执行速度远快于方案一,两者性能差距会随着符合条件的凭证数量增加而被放大:
- 方案一需要把所有符合条件的BKPF数据全部读取到内存内表,再做排序操作,数据量大的时候会占用大量内存,且排序耗时久,网络传输数据量也大。
- 方案二则是在数据库端直接完成筛选、排序,只返回一条数据,网络传输和内存占用都极小,数据库如果有
BUKRS+BLART+BELNR的复合索引,还能直接快速定位到目标数据,避免全表扫描。
更优实现方式
除了方案二,还可以用SELECT SINGLE替代UP TO 1 ROWS(效果一致,语法更简洁):
SELECT SINGLE belnr INTO lv_belnr FROM bkpf WHERE bukrs EQ ls_upload-bukrs AND blart EQ ls_upload-blart ORDER BY belnr DESCENDING.
另外可以检查是否有合适的函数模块,但实际上这类需求直接用数据库查询是最优的——因为函数模块底层大概率也是类似的查询逻辑,反而多了一层调用开销。关键是要确保BKPF表存在BUKRS、BLART、BELNR的复合索引,这能让查询效率最大化。
内容的提问来源于stack exchange,提问作者Hazzan Dalisay Ortuoste Jr.
相关产品推荐
相关产品推荐

