5

私は困惑しています。次のコードをコンパイルすると

REPORT zzy.

CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS:
      class_constructor,
      main.
  PRIVATE SECTION.
    TYPES: BEGIN OF t_record,
      transid TYPE sy-index,
      item1   TYPE char20,
      value1  TYPE p LENGTH 7 DECIMALS 2,
      value2  TYPE p LENGTH 7 DECIMALS 2,
      value3  TYPE p LENGTH 7 DECIMALS 2,
      value4  TYPE p LENGTH 7 DECIMALS 2,
    END OF t_record,
    tt_record TYPE STANDARD TABLE OF t_record WITH NON-UNIQUE KEY transid item1 WITH UNIQUE HASHED KEY sec_key COMPONENTS value1 value2 value3.
    CLASS-DATA:
      mt_record TYPE tt_record.
ENDCLASS.

CLASS lcl_main IMPLEMENTATION.
  METHOD class_constructor.
    DO 10 TIMES.
      INSERT VALUE t_record( transid = sy-index item1 = |Item{ sy-index }| value1 = sy-index value2 = sy-index / 2 value3 = sy-index / 4 value4 = 0 )
        INTO TABLE mt_record.
    ENDDO.
  ENDMETHOD.

  METHOD main.
    DATA:
      l_secs TYPE i,
      l_millisecs TYPE i,
      l_start TYPE timestampl,
      l_end   TYPE timestampl,
      l_diff  LIKE l_start.
    GET TIME STAMP FIELD l_start.
    LOOP AT mt_record INTO DATA(ls_record)
      WHERE value1 = '100.00' AND value2 = '150.0' AND value3 = '10.0'.

      ASSERT 1 = 1.

    ENDLOOP.
    GET TIME STAMP FIELD l_end.
    l_diff = l_end - l_start.

    WRITE: / l_diff.
  ENDMETHOD.
ENDCLASS.

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

次の警告が表示されます

プログラム ZZY
2 次キー「SEC_KEY」は完全に指定されています。ただし、アクセスには主
キーが使用されます。「SEC_KEY」を使ったアクセスの方が
効率的かチェック

しかし、このキーを指定するとUSING KEY sec_key、コンパイル時エラーが発生します!

REPORT zzy.

CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS:
      class_constructor,
      main.
  PRIVATE SECTION.
    TYPES: BEGIN OF t_record,
      transid TYPE sy-index,
      item1   TYPE char20,
      value1  TYPE p LENGTH 7 DECIMALS 2,
      value2  TYPE p LENGTH 7 DECIMALS 2,
      value3  TYPE p LENGTH 7 DECIMALS 2,
      value4  TYPE p LENGTH 7 DECIMALS 2,
    END OF t_record,
    tt_record TYPE STANDARD TABLE OF t_record WITH NON-UNIQUE KEY transid item1 WITH UNIQUE HASHED KEY sec_key COMPONENTS value1 value2 value3.
    CLASS-DATA:
      mt_record TYPE tt_record.
ENDCLASS.

CLASS lcl_main IMPLEMENTATION.
  METHOD class_constructor.
    DO 10 TIMES.
      INSERT VALUE t_record( transid = sy-index item1 = |Item{ sy-index }| value1 = sy-index value2 = sy-index / 2 value3 = sy-index / 4 value4 = 0 )
        INTO TABLE mt_record.
    ENDDO.
  ENDMETHOD.

  METHOD main.
    DATA:
      l_secs TYPE i,
      l_millisecs TYPE i,
      l_start TYPE timestampl,
      l_end   TYPE timestampl,
      l_diff  LIKE l_start.
    GET TIME STAMP FIELD l_start.
    LOOP AT mt_record INTO DATA(ls_record) USING KEY sec_key
      WHERE value1 = '100.00' AND value2 = '150.0' AND value3 = '10.0'.

      ASSERT 1 = 1.

    ENDLOOP.
    GET TIME STAMP FIELD l_end.
    l_diff = l_end - l_start.

    WRITE: / l_diff.
  ENDMETHOD.
ENDCLASS.

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

プログラム ZZY
キー「SEC_KEY」は、「HASHED KEY」タイプの 2 次キーです。これらの場合、すべての主要コンポーネントを提供する必要があります

ここで何が間違っていますか?

4

1 に答える 1

4

条件の構文ドキュメントにLOOP記載されているように、

セカンダリ テーブル キーが指定されている場合は、指定されているすべての WHERE 条件が最適化可能である必要があります。そうしないと、構文エラーが発生するか、例外が発生します。

何が比較可能で最適化可能で何がそうでないかのルールに飛び込むときは、コーヒーや好きな興奮剤を手元に十分に用意してください。この場合、指定された比較には aTYPE Pと a TYPE C(like '100.00') を含める必要がありますが、これは可能である必要がありますが、さらに長さが一致する必要がありますが、一致しません。ドキュメンテーションでさえ、

比較規則は複雑であるため (特に基本データ型の場合、比較型が左オペランドのデータ型と一致する場合を正確に詳述する一連の規則を作成することはお勧めできません。

結論: キー アクセスにはまったく同じ型を使用し、暗黙的な変換には決して依存しないでください。列に使用したのと同じ型を使用して変数または定数を宣言しvalueN、それを比較に使用すると、機能します。

于 2016-05-03T10:34:30.610 に答える