原文链接:https://blog.csdn.net/Buffalo_soldier/article/details/109772612
我们在写程序的时候可能会遇到用内表处理超大量数据的情况,比如取MSEG、BSEG表,内表里的数据如果超过2G就会报程序dump了,所以关键是要控制内表的数据量。
以下载一个系统表的数据为例,选择界面输入系统表名,用户点执行则将系统表数据下载到本地或进行其他处理。
第一步,计算系统表一条数据占用的内存;
第二步,计算内表最多可以存多少条数据;
第三步,每次处理最大条目数的数据。
示例代码:
*&---------------------------------------------------------------------*
*& Report ZCYCLE062
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zcycle062.
PARAMETERS : p_table TYPE ddobjname. "数据库表名
DATA : db_cursor TYPE cursor. "定义游标
DATA : lt_dfies TYPE TABLE OF dfies,
ls_dfies TYPE dfies,
struc_size TYPE i VALUE 0,
g_package_size TYPE i.
FIELD-SYMBOLS : <xtab> TYPE ANY TABLE. "取出的表数据
DATA : l_refitab TYPE REF TO data.
CREATE DATA l_refitab TYPE TABLE OF (p_table).
ASSIGN l_refitab->* TO <xtab>.
FIELD-SYMBOLS <otab> TYPE ANY . "读取表数据的表空间
* 取系统表结构
CALL FUNCTION 'DDIF_NAMETAB_GET'
EXPORTING
tabname = p_table
TABLES
dfies_tab = lt_dfies
EXCEPTIONS
not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
EXIT.
ENDIF.
** 每个数据包的逻辑
* 计算一条数据占用的内存
LOOP AT lt_dfies INTO ls_dfies.
struc_size = struc_size + ls_dfies-leng.
ENDLOOP.
***** 计算2G内存可以存储多少条数据 2G = 2147483648字节
g_package_size = 2147483648 / struc_size.
"打开游标
OPEN CURSOR WITH HOLD db_cursor FOR
SELECT * FROM (p_table)
BYPASSING BUFFER.
DO.
*** 每次取2g的数据包
"通过游标读取数据
FETCH NEXT CURSOR db_cursor
INTO CORRESPONDING FIELDS OF TABLE <xtab> "<xtab>就是从表里取出来的2g数据
PACKAGE SIZE g_package_size. "每次读取2G的数据
IF sy-subrc NE 0.
CLOSE CURSOR db_cursor.
EXIT. "没取到数据则跳出循环
ENDIF.
*** 对数据包的进一步操作
"读取内表信息
LOOP AT <xtab> ASSIGNING <otab>.
cl_demo_output=>write( <otab> ). "一行行写数据准备输出
ENDLOOP.
ENDDO.
cl_demo_output=>display( ). "一次性输出
输入
输出
同理,程序逻辑中遇到内表超内存dump也可以分批次处理,比如销售订单的全流程跟踪中,从VBAK中取出50万条销售订单数据,然后根据这些销售订单作为索引去取数据流中交货单、发票等等信息,一次性处理这50万条数据可能就会程序dump,可以定义一个索引内表,10万或者5万一次来执行后面的逻辑,从而避免程序dump。