• SAP 通过游标来分批从数据库表读取2G数据


    原文链接: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( ). "一次性输出
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    输入
    在这里插入图片描述
    输出
    在这里插入图片描述
    同理,程序逻辑中遇到内表超内存dump也可以分批次处理,比如销售订单的全流程跟踪中,从VBAK中取出50万条销售订单数据,然后根据这些销售订单作为索引去取数据流中交货单、发票等等信息,一次性处理这50万条数据可能就会程序dump,可以定义一个索引内表,10万或者5万一次来执行后面的逻辑,从而避免程序dump。

  • 相关阅读:
    渲染引擎什么情况下才会为特定的节点创建新的图层
    一文速通MybatisPlus
    C++ 设计模式 —— 桥接模式
    SpringSecurity源码学习一:过滤器执行原理
    Redis 主从复制
    P3853 [TJOI2007]路标设置——二分答案
    STM32 TIM定时器,配置,详解(1)
    二本4年软件测试经验,三面阿里(定薪35K),分享我的心得
    APP分发-CDN加速原理
    百度网盘加群图解教程
  • 原文地址:https://blog.csdn.net/qq_55488207/article/details/134513002