ABAP学习(31):异步Function以及批量数据处理


ABAP异步Function已经批量数据处理

ABAP异步调用Function

调用语法:

CALL FUNCTION Remotefunction STARTING NEW TASK Taskname

DESTINATION IN GROUP {group|DEFAULT}

[{CALLING meth}|{PERFORMING subr} ON END OF TASK]

EXPORTING...

TABLES ...

CHANGING...

EXCEPTIONS...

Taskname:唯一值,多次调用需要生成不同唯一的Taskname;

DESTINATION Dest:指定application servers,Tcode:RZ12,查看最大支持并行数Max. Requests in Que;

[{CALLING meth}|{PERFORMING subr} ON END OF TASK]:设置回调子函数FORM,或回调方法。Method必须是公共Method,并且有输入参数p_task,类型clike;Subroutine必须Using p_task type clike。p_task其实就是调用时的Taskname。

EXPORTING...:输入参数

TABLES ...:输入输出Table类型参数

EXCEPTIONS...:默认三种Exception,resource_failure,当没有多余并行资源时,返回这个exception.

[EXCEPTIONS [exc1 = n1 exc2 = n2 ...]
                [system_failure = ns [MESSAGE smess]]
                [communication_failure = nc [MESSAGE cmess]]
                [resource_failure      = nr [MESSAGE rmess]]
                [OTHERS = n_others]].

回调函数接收执行结果:

RECEIVE RESULTS FROM FUNCTION func

parameter list

[KEEPING TASK].

KEEPING TASK:当回调函数执行完后,保持连接,可以通过Taskname执行获得相同全局参数;

parameter list:异步函数调用参数

[IMPORTING  p1 = a1 p2 = a2 ...]

[TABLES     t1 = itab1 t2 = itab2 ...]

[EXCEPTIONS exc1 = n1 exc2 = n2 ... [MESSAGE mess]

[OTHERS = n_others]].

WAIT阻塞当前主逻辑执行,只有在有回调函数的function使用,阻塞主逻辑,当回调函数执行后,反复执行判断。

WAIT UNTIL log_exp [UP TO sec SECONDS].

示例1:使用类方法

?"类方式异步调用function
CLASS zcl_parellel DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:main.
    CLASS-METHODS:m_callback IMPORTING p_task TYPE clike.
  PRIVATE SECTION.
    TYPES:BEGIN OF s_task,
            name TYPE char10,
            lines TYPE i,
          END OF s_task.
    CLASS-DATA:lt_task TYPE TABLE OF s_task.
    CLASS-DATA:ls_task LIKE LINE OF lt_task.
    CLASS-DATA:lv_count_suc TYPE i.
ENDCLASS.
CLASS zcl_parellel IMPLEMENTATION.
  "实现main函数
  METHOD main.
    DATA:lv_start TYPE i.
    DATA:lv_name TYPE c LENGTH 8.
    DATA:lv_len TYPE i VALUE 10000.
    DATA:lt_table TYPE TABLE OF ztom_data.
    DATA:lv_count_task TYPE i.
    DO 10 TIMES.
      lv_start = ( sy-index - 1 ) * lv_len.
      lv_name = 'tax' && sy-index.
      "异步调用function
      CALL FUNCTION 'ZTOM_MODIFY'
      STARTING NEW TASK lv_name
      DESTINATION IN GROUP 'parallel_generators'
      CALLING m_callback ON END OF TASK
      EXPORTING
        iv_name = lv_name
        iv_start = lv_start
        iv_len = lv_len
      TABLES
        t_data = lt_table
      EXCEPTIONS
        system_failure        = 1
        communication_failure = 2
        resource_failure      = 3.
      IF sy-subrc = 0.
        lv_count_task = lv_count_task + 1.
      ELSE.
        WRITE:/ 'some error'.
      ENDIF.
      WAIT UNTIL lv_count_suc >= lv_count_task.
      LOOP AT lt_task INTO ls_task.
        WRITE:/ ls_task-name,ls_task-lines.
      ENDLOOP.
    ENDDO.
  ENDMETHOD.
  "实现回调函数
  METHOD m_callback.
    DATA:lt_table TYPE TABLE OF ztom_data.
    DATA:lv_line TYPE i.
    RECEIVE RESULTS FROM FUNCTION 'ZTOM_MODIFY'
      TABLES
        t_data = lt_table.
    lv_line = lines( lt_table ).
    "记录task内表
    CLEAR ls_task.
    ls_task-name = p_task.
    ls_task-lines = lv_line.
    APPEND ls_task TO lt_task.
    "成功回调计数
    lv_count_suc = lv_count_suc + 1.
  ENDMETHOD.
ENDCLASS.
?

方式2:使用Subroutine子函数

?FORM f_update_data USING tax_id TYPE clike.
  DATA:lt_table TYPE TABLE OF ztom_data.
  DATA:lv_line TYPE i.
  RECEIVE RESULTS FROM FUNCTION 'ZTOM_MODIFY'
    TABLES
      t_data = lt_table.
  lv_line = lines( lt_table ).
  lv_count_suc = lv_count_suc + 1.
ENDFORM.
"异步function
FORM f_test_parellel.
  "RZ12查看
  DATA:lv_start TYPE i.
  DATA:lv_len TYPE i VALUE 10000.
  DATA:lv_name TYPE C LENGTH 8.
  DATA:lt_table TYPE TABLE OF ztom_data.

  GET RUN TIME FIELD lv_time_begin.
  DO 10 TIMES.
    lv_start = ( sy-index - 1 ) * lv_len.
    lv_name = 'tax' && sy-index.
    "异步调用function
    CALL FUNCTION 'ZTOM_MODIFY'
    STARTING NEW TASK lv_name
    DESTINATION IN GROUP 'parallel_generators'
    PERFORMING f_update_data ON END OF TASK
    EXPORTING
      iv_name = lv_name
      iv_start = lv_start
      iv_len = lv_len
    TABLES
      t_data = lt_table.
    IF sy-subrc = 0.
      lv_count_parell = lv_count_parell + 1.
    ELSE.
      WRITE:/ 'some error'.
    ENDIF.
  ENDDO.
  WAIT UNTIL lv_count_suc >= lv_count_parell.
  GET RUN TIME FIELD lv_time_end.
  lv_time = lv_time_end - lv_time_begin.
  WRITE:/ lv_time.
ENDFORM.
?

ABAP内表行数最大差不多4千万笔数据,当数据库表数据大于这个条数时,对数据进行处理不能一次性读入内表,需要分批处理。

?"大批量数据处理
FORM f_test_select_package.
  DATA:lt_data TYPE TABLE OF ztom_data.
  DATA:ls_data LIKE LINE OF lt_data.
  DATA:lv_c1 TYPE cursor.

  "1.使用select package
  SELECT * INTO TABLE lt_data
    PACKAGE SIZE 100
    FROM ztom_data.
    "中间处理逻辑
    "因为内表容量限制,不能一次性读入内表处理,将大量数据分100次处理
  ENDSELECT.

  "2.使用open cursor
  OPEN CURSOR lv_c1 FOR
    SELECT * FROM ztom_data.
  DO.
    "每次处理1000条数据
    FETCH NEXT CURSOR lv_c1 INTO TABLE lt_data PACKAGE SIZE 1000.
    IF sy-subrc <> 0.
      EXIT.
    ENDIF.
    LOOP AT lt_data INTO ls_data.
      "处理读出来的数据
    ENDLOOP.
  ENDDO.

ENDFORM.
?