zoukankan      html  css  js  c++  java
  • SAP RFC函数RFC_READ_TABLE使用与优化

    RFC_READ_TABLE

    第三方系统可通过RFC调用此函数直接访问(查询)SAP R/3系统的数据表。
    合理使用此函数可以大幅度减少第三方系统集成数据接口开发量。

    查询表结构

    在这里插入图片描述

    查询数据

    在这里插入图片描述

    导入参数

    • QUERY_TABLE 表名称(必填)
    • DELIMITER 分隔符,默认值空格
      在返回数据的DATA表项目中,通过此参数传递的分隔符分隔字段值,传空格则不包含分隔符
    • NO_DATA 不传输数据,默认值为空格
      如果此项不为空格,则函数不返回表数据,只返回字段信息
    • ROWSKIPS 跳行数,默认值0
    • ROWCOUNT 行数,默认值0
      行数为0则返回所有行

    表参数

    • OPTIONS 选择条件语句(传入)
    1. TEXT where语句文本
    • FIELDS 字段信息(传入/传出)
    1. FIELDNAME 字段名
    2. OFFSET 偏移量
    3. LENGTH 长度
    4. TYPE 数据类型
    5. FIELDTEXT 字段描述
      作为传入参数时,只需要传递FIELDNAME字段值,用于选择需要返回的字段;
      作为传出参数时,返回字段相关信息
    • DATA 表数据(传出)
    1. WA 行记录数据

    优化

    1. 分页数据错乱

    此函数可通过ROWSKIPS,ROWCOUNT参数实现分页查询,但实际使用时会发现返回的数据并没有排序,导致分页数据错乱。

    解决办法

    修改程序使用主键排序查询

    #  SELECT * FROM (QUERY_TABLE) INTO <WA> WHERE (OPTIONS).
    SELECT * FROM (QUERY_TABLE) INTO <WA> WHERE (OPTIONS) ORDER BY PRIMARY KEY.
    

    2. DATA数据长度限制

    此函数一次性查询的字段不可过多,总长度超过DATA字段类型长度512时将抛出异常DATA_BUFFER_EXCEEDED

    解决办法

    将返回结果按512长度拆分到多个data table返回
    在这里插入图片描述

    FUNCTION ZRFC_READ_TABLE .
    *"----------------------------------------------------------------------
    *"*"本地接口:
    *"  IMPORTING
    *"     VALUE(QUERY_TABLE) LIKE  DD02L-TABNAME
    *"     VALUE(DELIMITER) LIKE  SONV-FLAG DEFAULT SPACE
    *"     VALUE(NO_DATA) LIKE  SONV-FLAG DEFAULT SPACE
    *"     VALUE(ROWSKIPS) LIKE  SOID-ACCNT DEFAULT 0
    *"     VALUE(ROWCOUNT) LIKE  SOID-ACCNT DEFAULT 0
    *"  TABLES
    *"      OPTIONS STRUCTURE  RFC_DB_OPT
    *"      FIELDS STRUCTURE  RFC_DB_FLD
    *"      DATA STRUCTURE  TAB512
    *"      DATA1 STRUCTURE  TAB512
    *"      DATA2 STRUCTURE  TAB512
    *"      DATA3 STRUCTURE  TAB512
    *"      DATA4 STRUCTURE  TAB512
    *"  EXCEPTIONS
    *"      TABLE_NOT_AVAILABLE
    *"      TABLE_WITHOUT_DATA
    *"      OPTION_NOT_VALID
    *"      FIELD_NOT_VALID
    *"      NOT_AUTHORIZED
    *"      DATA_BUFFER_EXCEEDED
    *"----------------------------------------------------------------------
    "
    CALL FUNCTION 'VIEW_AUTHORITY_CHECK'
         EXPORTING
              VIEW_ACTION                    = 'S'
              VIEW_NAME                      = QUERY_TABLE
         EXCEPTIONS
              NO_AUTHORITY                   = 2
              NO_CLIENTINDEPENDENT_AUTHORITY = 2
              NO_LINEDEPENDENT_AUTHORITY     = 2
              OTHERS                         = 1.
    
    IF SY-SUBRC = 2.
      RAISE NOT_AUTHORIZED.
    ELSEIF SY-SUBRC = 1.
      RAISE TABLE_NOT_AVAILABLE.
    ENDIF.
    
    * ----------------------------------------------------------------------
    *  find out about the structure of QUERY_TABLE
    * ----------------------------------------------------------------------
    DATA BEGIN OF TABLE_STRUCTURE OCCURS 10.
            INCLUDE STRUCTURE DFIES.
    DATA END OF TABLE_STRUCTURE.
    "DATA TABLE_HEADER LIKE X030L.
    DATA TABLE_TYPE TYPE DD02V-TABCLASS.
    
    CALL FUNCTION 'DDIF_FIELDINFO_GET'
      EXPORTING
        TABNAME              = QUERY_TABLE
    *   FIELDNAME            = ' '
    *   LANGU                = SY-LANGU
    *   LFIELDNAME           = ' '
    *   ALL_TYPES            = ' '
    *   GROUP_NAMES          = ' '
      IMPORTING
    *   X030L_WA             =
        DDOBJTYPE            = TABLE_TYPE
    *   DFIES_WA             =
    *   LINES_DESCR          =
      TABLES
        DFIES_TAB            = TABLE_STRUCTURE
    *   FIXED_VALUES         =
      EXCEPTIONS
        NOT_FOUND            = 1
        INTERNAL_ERROR       = 2
        OTHERS               = 3
              .
    IF SY-SUBRC <> 0.
      RAISE TABLE_NOT_AVAILABLE.
    ENDIF.
    IF TABLE_TYPE = 'INTTAB'.
      RAISE TABLE_WITHOUT_DATA.
    ENDIF.
    
    * ----------------------------------------------------------------------
    *  isolate first field of DATA as output field
    *  (i.e. allow for changes to structure DATA!)
    * ----------------------------------------------------------------------
    DATA LINE_LENGTH TYPE I.
    FIELD-SYMBOLS <D>.
    ASSIGN COMPONENT 0 OF STRUCTURE DATA TO <D>.
    DESCRIBE FIELD <D> LENGTH LINE_LENGTH in character mode.
    * PSR D1-D4 --------------------
    DATA LINE_LENGTH1 TYPE I.
    FIELD-SYMBOLS <D1>.
    ASSIGN COMPONENT 0 OF STRUCTURE DATA1 TO <D1>.
    DESCRIBE FIELD <D1> LENGTH LINE_LENGTH1 in character mode.
    DATA LINE_LENGTH2 TYPE I.
    FIELD-SYMBOLS <D2>.
    ASSIGN COMPONENT 0 OF STRUCTURE DATA2 TO <D2>.
    DESCRIBE FIELD <D2> LENGTH LINE_LENGTH2 in character mode.
    DATA LINE_LENGTH3 TYPE I.
    FIELD-SYMBOLS <D3>.
    ASSIGN COMPONENT 0 OF STRUCTURE DATA3 TO <D3>.
    DESCRIBE FIELD <D3> LENGTH LINE_LENGTH3 in character mode.
    DATA LINE_LENGTH4 TYPE I.
    FIELD-SYMBOLS <D4>.
    ASSIGN COMPONENT 0 OF STRUCTURE DATA4 TO <D4>.
    DESCRIBE FIELD <D4> LENGTH LINE_LENGTH4 in character mode.
    DATA TOTALLENGTH TYPE I.
    * PSR D1-D4 --------------------
    * ----------------------------------------------------------------------
    *  if FIELDS are not specified, read all available fields
    * ----------------------------------------------------------------------
    DATA NUMBER_OF_FIELDS TYPE I.
    DESCRIBE TABLE FIELDS LINES NUMBER_OF_FIELDS.
    IF NUMBER_OF_FIELDS = 0.
      LOOP AT TABLE_STRUCTURE.
        MOVE TABLE_STRUCTURE-FIELDNAME TO FIELDS-FIELDNAME.
        APPEND FIELDS.
      ENDLOOP.
    ENDIF.
    
    * ----------------------------------------------------------------------
    *  for each field which has to be read, copy structure information
    *  into tables FIELDS_INT (internal use) and FIELDS (output)
    * ----------------------------------------------------------------------
    DATA: BEGIN OF FIELDS_INT OCCURS 10,
            FIELDNAME  LIKE TABLE_STRUCTURE-FIELDNAME,
            TYPE       LIKE TABLE_STRUCTURE-INTTYPE,
            DECIMALS   LIKE TABLE_STRUCTURE-DECIMALS,
            LENGTH_SRC LIKE TABLE_STRUCTURE-INTLEN,
            LENGTH_DST LIKE TABLE_STRUCTURE-LENG,
            OFFSET_SRC LIKE TABLE_STRUCTURE-OFFSET,
            OFFSET_DST LIKE TABLE_STRUCTURE-OFFSET,
          END OF FIELDS_INT,
          LINE_CURSOR TYPE I.
    
    LINE_CURSOR = 0.
    *  for each field which has to be read ...
    LOOP AT FIELDS.
    
      READ TABLE TABLE_STRUCTURE WITH KEY FIELDNAME = FIELDS-FIELDNAME.
      IF SY-SUBRC NE 0.
        RAISE FIELD_NOT_VALID.
      ENDIF.
    
    * compute the place for field contents in DATA rows:
    * if not first field in row, allow space for delimiter
      IF LINE_CURSOR <> 0.
        IF NO_DATA EQ SPACE AND DELIMITER NE SPACE.
          MOVE DELIMITER TO DATA+LINE_CURSOR.
        ENDIF.
        LINE_CURSOR = LINE_CURSOR + STRLEN( DELIMITER ).
      ENDIF.
    
    * ... copy structure information into tables FIELDS_INT
    * (which is used internally during SELECT) ...
      FIELDS_INT-FIELDNAME  = TABLE_STRUCTURE-FIELDNAME.
      FIELDS_INT-LENGTH_SRC = TABLE_STRUCTURE-INTLEN.
      FIELDS_INT-LENGTH_DST = TABLE_STRUCTURE-LENG.
      FIELDS_INT-OFFSET_SRC = TABLE_STRUCTURE-OFFSET.
      FIELDS_INT-OFFSET_DST = LINE_CURSOR.
      FIELDS_INT-TYPE       = TABLE_STRUCTURE-INTTYPE.
      FIELDS_INT-DECIMALS   = TABLE_STRUCTURE-DECIMALS.
    * compute the place for contents of next field in DATA rows
      LINE_CURSOR = LINE_CURSOR + TABLE_STRUCTURE-LENG.
    
    * PSR D1-D4 --------------------
      IF LINE_CURSOR > LINE_LENGTH + LINE_LENGTH1 + LINE_LENGTH2 + LINE_LENGTH3 + LINE_LENGTH4 AND NO_DATA EQ SPACE.
    * PSR D1-D4 --------------------
        RAISE DATA_BUFFER_EXCEEDED.
      ENDIF.
      TOTALLENGTH = LINE_CURSOR.
    
      APPEND FIELDS_INT.
    
    * ... and into table FIELDS (which is output to the caller)
      FIELDS-FIELDTEXT = TABLE_STRUCTURE-FIELDTEXT.
      FIELDS-TYPE      = TABLE_STRUCTURE-INTTYPE.
      FIELDS-LENGTH    = FIELDS_INT-LENGTH_DST.
      FIELDS-OFFSET    = FIELDS_INT-OFFSET_DST.
      MODIFY FIELDS.
    
    ENDLOOP.
    * end of loop at FIELDS
    
    * ----------------------------------------------------------------------
    *  read data from the database and copy relevant portions into DATA
    * ----------------------------------------------------------------------
    * output data only if NO_DATA equals space (otherwise the structure
    * information in FIELDS is the only result of the module)
    IF NO_DATA EQ SPACE.
    
    DATA: BEGIN OF WORK, BUFFER(30000), END OF WORK.
    * PSR-----------
    DATA: DATABUFFER TYPE C LENGTH 30000.
    * PSR-----------
    FIELD-SYMBOLS: <WA> TYPE ANY, <COMP> TYPE ANY.
    ASSIGN WORK TO <WA> CASTING TYPE (QUERY_TABLE).
    
    IF ROWCOUNT > 0.
      ROWCOUNT = ROWCOUNT + ROWSKIPS.
    ENDIF.
    * #CP-SUPPRESS: FP <This FM obolete.note 382318.Hence no need of change>
      SELECT * FROM (QUERY_TABLE) INTO <WA> WHERE (OPTIONS) ORDER BY PRIMARY KEY.
    
        IF SY-DBCNT GT ROWSKIPS.
          DATABUFFER = ''.
    *   copy all relevant fields into DATA (output) table
          LOOP AT FIELDS_INT.
            IF FIELDS_INT-TYPE = 'P'.
            ASSIGN COMPONENT FIELDS_INT-FIELDNAME
                OF STRUCTURE <WA> TO <COMP>
                TYPE     FIELDS_INT-TYPE
                DECIMALS FIELDS_INT-DECIMALS.
            ELSE.
            ASSIGN COMPONENT FIELDS_INT-FIELDNAME
                OF STRUCTURE <WA> TO <COMP>
                TYPE     FIELDS_INT-TYPE.
            ENDIF.
            MOVE <COMP> TO
                DATABUFFER+FIELDS_INT-OFFSET_DST(FIELDS_INT-LENGTH_DST).
          ENDLOOP.
    *   end of loop at FIELDS_INT
          DATA = DATABUFFER+0(512).
          APPEND DATA.
    
          IF TOTALLENGTH > 512 .
            DATA1 = DATABUFFER+512(512).
            APPEND DATA1.
          ENDIF.
          IF TOTALLENGTH > 1024.
            DATA2 = DATABUFFER+1024(512).
            APPEND DATA2.
          ENDIF.
          IF TOTALLENGTH > 1536.
            DATA3 = DATABUFFER+1536(512).
            APPEND DATA3.
          ENDIF.
          IF TOTALLENGTH > 2048.
            DATA4 = DATABUFFER+2048(512).
            APPEND DATA4.
          ENDIF.
    
          IF ROWCOUNT > 0 AND SY-DBCNT GE ROWCOUNT. EXIT. ENDIF.
    
        ENDIF.
    
      ENDSELECT.
    
    ENDIF.
    
    ENDFUNCTION.
    
  • 相关阅读:
    html 入门 "地表最强"干货 你值得拥有
    python信号量
    死锁 与 递归锁
    互斥锁
    进程之间的通讯
    进程与多道技术
    进程对象常用属性
    开启子进程的方式2
    牛客多校赛2K Keyboard Free
    省选刷题小记 (06~10)
  • 原文地址:https://www.cnblogs.com/luguojun/p/14294675.html
Copyright © 2011-2022 走看看