使用字段符号处理内部表

学习目标

  • 使用字段符号处理内部表。

用于访问内部表的字段符号

您已经学习了如何使用结构作为工作区,对内部表进行迭代。使用此技术时,系统会将数据从内部表复制到工作区。然后在使用 MODIFY 语句将工作区的内容复制回内部表之前对其进行更改。

如果使用此技术处理大型内部表,则可能会由于反复复制数据的成本而导致性能问题。可通过用字段符号替换工作区来降低这些成本。

用字段符号替换工作区

字段符号是一个指针。指针是一个数据对象,它知道不同对象的内存地址,并允许您操作该对象。对于内部表,指针允许您对内部表的行进行寻址,而无需先将其复制到工作区域中。由于直接使用表行而不是工作区,因此不必将更改复制回内部表。

要定义字段符号,请使用 FIELD-SYMBOLS 语句并为字段符号分配名称。名称必须包含在尖括号中。还可以为字段符号分配类型。如果要使用字段符号处理内部表,则使用内部表的行类型定义字段符号,就像使用工作区一样。

要在内部表的循环中使用字段符号,请使用 ASSIGNING 语句中的 LOOP 附加项。在每个循环传递中,指针现在指向内部表的相应行,您可以直接更改其内容。由于字段符号具有内部表的行类型,因此可以将其视为相应结构。在字段符号名称之后,可以键入破折号,后跟要更改的字段。

由于您直接使用内部表而不是结构,因此不需要 MODIFY 语句。通过避免复制数据,可以显著提高循环的性能。

运行时比较

在此,您可以查看运行时分析的结果,其中内部表使用 MODIFY 语句更新,另一个使用字段符号更新。在这种情况下,字段符号花费的时间比 modify 语句少 40%。通常,使用字段符号而不是工作区更新内部表时,可以节省 25–40% 的运行时。读取操作的性能增益较小。

试用:用于访问内部表的字段符号

  1. 创建实施接口 IF_OO_ADT_CLASSRUN 的新类。

  2. 将以下代码片段复制到方法 if_oo_adt_classrun~main() 的实施部分:

METHOD if_oo_adt_classrun~main.
* Execute this class using Profile As->ABAP Application
* In the analysis, look at the comparative runtimes of
* the methods loop_work_area( ) and loop_field_symbol( )
data(flights) = new lcl_demo( ).
flights->use_work_area( ).
flights->use_field_symbol( ).
out->write( 'Done' ).
  1. 切换到 局部类型 标签并将以下代码片段复制到编辑器中:

CLASS lcl_demo DEFINITION.
PUBLIC SECTION.
METHODS use_work_area.
METHODS use_field_symbol.
PRIVATE SECTION.
TYPES t_flights TYPE STANDARD TABLE OF /dmo/flight WITH NON-UNIQUE KEY carrier_id connection_id flight_date.
METHODS loop_field_symbol CHANGING c_flights TYPE t_Flights.
METHODS loop_Work_area CHANGING c_flights TYPE t_flights.
ENDCLASS.
CLASS lcl_demo IMPLEMENTATION.
METHOD use_field_symbol.
DATA flights TYPE t_flights.
SELECT FROM /dmo/flight FIELDS * INTO TABLE @flights.
loop_field_symbol( CHANGING c_flights = flights ).
ENDMETHOD.
METHOD use_work_area.
DATA flights TYPE t_flights.
SELECT FROM /dmo/flight FIELDS * INTO TABLE @flights.
loop_work_area( CHANGING c_flights = flights ).
ENDMETHOD.
METHOD loop_field_symbol.
LOOP AT c_flights ASSIGNING FIELD-SYMBOL().
-seats_occupied += 1.
ENDLOOP.
ENDMETHOD.
METHOD loop_work_area.
LOOP AT c_flights INTO DATA(flight).
flight-seats_occupied += 1.
MODIFY c_flights FROM flight.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
  1. 选择 Ctrl + F3 激活类。

  2. 右键单击编辑器,然后选择 参数文件作为... → ABAP 应用程序(控制台) 。

  3. 在 详细信息 中,取消选中复选框 SQL 数据库访问 ,然后选择 完成 。

  4. 切换到 ABAP 分析器 透视图并双击跟踪项目(可能需要先刷新显示)。

  5. 选择 Hit List 。

  6. 比较方法 loop_Work_area( ) 和 loop_field_symbol( ) 的运行时。

在循环中使用字段符号

您注意到局部类 LCL_PASSENGER_FLIGHTGET_FLIGHTS_BY_CARRIER 方法中的理解仅访问工作区的九个组件中的三个。为提高性能,您将分配字段符号,而不是将整个表行复制到工作区。

模板:

  • /LRN/CL_S4D401_ITS_PROCESSING(全局类)

解决方案:

  • /LRN/CL_S4D401_ITS_FSYM(全局类)

任务 1: 复制模板(可选)

复制模板类 /LRN/CL_S4D401_ITS_PROCESSING。如果已完成上一练习,则可以跳过此任务并继续编辑类 ZCL_##_SOLUTION

步骤

  1. 将类 /LRN/CL_S4D401_ITS_PROCESSING 复制到您自己的包中的类(建议名称:ZCL_##_SOLUTION,其中 ## 代表组编号)。

  2. 在项目浏览器中,右键单击类 /LRN/CL_S4D401_ITS_PROCESSING 以打开内容菜单。

  3. 从上下文菜单中,选择复制....

  4. 在包字段中输入的名称。在名称字段中,输入 ZCL_##_SOLUTION,其中 ## 代表组编号。

  5. 选择下一步

  6. 确认传输请求并选择完成

  7. 激活复制。

  8. Ctrl + F3 激活类。

任务 2: 使用字段符号

更改本地类 LCL_PASSENGER_FLIGHT 中方法 GET_FLIGHTS_BY_CARRIER 的实施。在理解中,使用字段符号替换工作区。

步骤

  1. 在局部类 LCL_PASSENGER_FLIGHT 中,导航至方法 GET_FLIGHTS_BY_CARRIER 的实施。

  2. 如之前练习所述执行该步骤。

  3. 调整 VALUE 语句,以便在每次迭代中将字段符号分配到内部表的当前行(字段符号的建议名称:<flight>)。

  4. 如下调整代码:

*  r_result = VALUE #(
*               FOR flight IN flights_buffer
r_result = VALUE #(
FOR <flight> IN flights_buffer
  1. 调整 VALUE 表达式内的代码。使用字段符号 (<****flight>) 替换工作区(航班)的任何用途。

  2. 如下调整代码:

*  r_result = VALUE #(
*               FOR flight IN flights_buffer
*                 WHERE ( carrier_id = i_carrier_id ) (
*                   NEW lcl_passenger_flight(
*                         i_carrier_id    = flight-carrier_id
*                         i_connection_id = flight-connection_id
*                         i_flight_date   = flight-flight_date )
*                                                     )
*             ).
r_result = VALUE #(
FOR <flight> IN flights_buffer
WHERE ( carrier_id = i_carrier_id ) (
NEW lcl_passenger_flight(
i_carrier_id    = <flight>-carrier_id
i_connection_id = <flight>-connection_id
i_flight_date   = <flight>-flight_date )
)
).
  1. 以控制台应用形式激活并测试全局类。

  2. Ctrl + F3

  3. F9