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

如果使用此技术处理大型内部表,则可能会由于反复复制数据的成本而导致性能问题。可通过用字段符号替换工作区来降低这些成本。
用字段符号替换工作区
字段符号是一个指针。指针是一个数据对象,它知道不同对象的内存地址,并允许您操作该对象。对于内部表,指针允许您对内部表的行进行寻址,而无需先将其复制到工作区域中。由于直接使用表行而不是工作区,因此不必将更改复制回内部表。

要定义字段符号,请使用 FIELD-SYMBOLS 语句并为字段符号分配名称。名称必须包含在尖括号中。还可以为字段符号分配类型。如果要使用字段符号处理内部表,则使用内部表的行类型定义字段符号,就像使用工作区一样。
要在内部表的循环中使用字段符号,请使用 ASSIGNING 语句中的 LOOP 附加项。在每个循环传递中,指针现在指向内部表的相应行,您可以直接更改其内容。由于字段符号具有内部表的行类型,因此可以将其视为相应结构。在字段符号名称之后,可以键入破折号,后跟要更改的字段。
由于您直接使用内部表而不是结构,因此不需要 MODIFY 语句。通过避免复制数据,可以显著提高循环的性能。
运行时比较

在此,您可以查看运行时分析的结果,其中内部表使用 MODIFY 语句更新,另一个使用字段符号更新。在这种情况下,字段符号花费的时间比 modify 语句少 40%。通常,使用字段符号而不是工作区更新内部表时,可以节省 25–40% 的运行时。读取操作的性能增益较小。
试用:用于访问内部表的字段符号
创建实施接口 IF_OO_ADT_CLASSRUN 的新类。
将以下代码片段复制到方法 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' ).
切换到 局部类型 标签并将以下代码片段复制到编辑器中:
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.
选择 Ctrl + F3 激活类。
右键单击编辑器,然后选择 参数文件作为... → ABAP 应用程序(控制台) 。
在 详细信息 中,取消选中复选框 SQL 数据库访问 ,然后选择 完成 。
切换到 ABAP 分析器 透视图并双击跟踪项目(可能需要先刷新显示)。
选择 Hit List 。
比较方法 loop_Work_area( ) 和 loop_field_symbol( ) 的运行时。
在循环中使用字段符号
您注意到局部类 LCL_PASSENGER_FLIGHT 的 GET_FLIGHTS_BY_CARRIER 方法中的理解仅访问工作区的九个组件中的三个。为提高性能,您将分配字段符号,而不是将整个表行复制到工作区。
模板:
/LRN/CL_S4D401_ITS_PROCESSING(全局类)
解决方案:
/LRN/CL_S4D401_ITS_FSYM(全局类)
任务 1: 复制模板(可选)
复制模板类 /LRN/CL_S4D401_ITS_PROCESSING。如果已完成上一练习,则可以跳过此任务并继续编辑类 ZCL_##_SOLUTION。
步骤
将类
/LRN/CL_S4D401_ITS_PROCESSING复制到您自己的包中的类(建议名称:ZCL_##_SOLUTION,其中 ## 代表组编号)。在项目浏览器中,右键单击类
/LRN/CL_S4D401_ITS_PROCESSING以打开内容菜单。从上下文菜单中,选择复制....
在包字段中输入包的名称。在名称字段中,输入
ZCL_##_SOLUTION,其中 ## 代表组编号。选择下一步。
确认传输请求并选择完成。
激活复制。
按
Ctrl + F3激活类。
任务 2: 使用字段符号
更改本地类 LCL_PASSENGER_FLIGHT 中方法 GET_FLIGHTS_BY_CARRIER 的实施。在理解中,使用字段符号替换工作区。
步骤
在局部类
LCL_PASSENGER_FLIGHT中,导航至方法GET_FLIGHTS_BY_CARRIER的实施。如之前练习所述执行该步骤。
调整 VALUE 语句,以便在每次迭代中将字段符号分配到内部表的当前行(字段符号的建议名称:
<flight>)。如下调整代码:
* r_result = VALUE #(
* FOR flight IN flights_buffer
r_result = VALUE #(
FOR <flight> IN flights_buffer
调整 VALUE 表达式内的代码。使用字段符号 (
<****flight>) 替换工作区(航班)的任何用途。如下调整代码:
* 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 )
)
).
以控制台应用形式激活并测试全局类。
按
Ctrl + F3。按
F9。