传递字段符号作为更改参数会导致短转储。为什么?

问题描述 投票:0回答:3

为什么 SAP 试图变得比它必须的更聪明并在以下情况下生成短转储?

REPORT zzy.

CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS:
      main.
  PRIVATE SECTION.
    TYPES:
      BEGIN OF t_my_type,
        hierlevel TYPE i,
        groupname TYPE ktext,
        result    TYPE p LENGTH 9 DECIMALS 2,
      END OF t_my_type,
      tt_my_type TYPE HASHED TABLE OF t_my_type WITH UNIQUE KEY hierlevel groupname.
    CLASS-METHODS:
      change
        CHANGING
          cs_my_type TYPE t_my_type.
ENDCLASS.

CLASS lcl_main IMPLEMENTATION.
  METHOD main.
    DATA:
      lt_my_table TYPE tt_my_type.

    INSERT VALUE #( hierlevel = 0 groupname = 'MY_GROUP' result = '0.0' ) INTO TABLE lt_my_table
      ASSIGNING FIELD-SYMBOL(<fs_my_type>).

    change(
      CHANGING
        cs_my_type = <fs_my_type>
    ).
  ENDMETHOD.

  METHOD change.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  lcl_main=>main( ).

方法没有任何变化

change
但在我看到的短转储的描述中

字段

<FS_MY_TYPE>-HIERLEVEL
将分配一个新值,但该字段至少部分受到保护以防止更改。

看来 SAP 试图变得比应有的更聪明。如果我实际上尝试更改关键字段之一,我会理解是否生成了短转储。为什么要这样设计?

abap
3个回答
1
投票

我刚刚发现简短转储中的进一步描述有这样的

以下内容不受更改:
- 如果使用 ASSIGN 分配的字段是,则使用字段符号访问 部分或完全受到保护(例如内部的关键组件) SORTED 或 HASHED TABLE 类型的表)。

对我来说有点奇怪,但看起来像是一个设计决定。也许在技术上很难只检查实际受保护的字段。


0
投票

使用

INSERT...ASSIGNING <fs_row>
语法时,您应该始终注意适用于相应字段符号的限制。根据 SAP 的说法,READ TABLE ...ASSIGNING <fs_row> 中存在的
相同
限制也适用于
INSERT
施工。特别是,它们是:

只要字段符号指向该行,就可以对 字段符号修改内表中的行。下列 限制适用于修改主要和次要的关键字段 表键:

  • 排序表和散列表的主表键的关键字段 表是只读的,不得修改。这将使 内部表管理。尝试这样做通常会引发 无法处理的异常。
    ...

同样的限制也适用于内联声明
正如我们在代码中看到的,您对方法的参数使用隐式传递引用声明。但按引用传递不会为参数创建任何本地数据对象,并且使用实际参数,这要求它们可写。这是你问题的关键。


0
投票

有趣的是,我们可以将数据引用作为更改后的参数传递,并且它可以工作。系统允许您更改非关键字段而不会出错,并针对关键字段更改抛出一个简短的转储。

    REPORT zzy.

CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS:
      main.
  PRIVATE SECTION.
    TYPES:
      BEGIN OF t_my_type,
        hierlevel TYPE i,
        groupname TYPE ktext,
        result    TYPE p LENGTH 9 DECIMALS 2,
      END OF t_my_type,
      tt_my_type TYPE HASHED TABLE OF t_my_type WITH UNIQUE KEY hierlevel groupname.
    CLASS-METHODS:
      change
        CHANGING
          cs_my_type TYPE REF TO t_my_type.
ENDCLASS.

CLASS lcl_main IMPLEMENTATION.
  METHOD main.
    DATA:
      lt_my_table TYPE tt_my_type.
    DATA ls_ref TYPE REF TO t_my_type.
    INSERT VALUE #( hierlevel = 0 groupname = 'MY_GROUP' result = '0.0' ) INTO TABLE lt_my_table
      ASSIGNING FIELD-SYMBOL(<fs_my_type>).

    GET REFERENCE OF <fs_my_type> INTO ls_ref.
    change(
      CHANGING
        cs_my_type = ls_ref
    ).

    write: | { <fs_my_type>-result }|.
  ENDMETHOD.

  METHOD change.
*    cs_my_type->*-groupname = 'GRP2'.  "Short dump: Assignment error: Overwriting of a protected field.
    cs_my_type->*-result = '10.1'.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  lcl_main=>main( ).
© www.soinside.com 2019 - 2024. All rights reserved.