【问题标题】:How to access the data in the table used for the FOR ALL ENTRIES statement?如何访问用于 FOR ALL ENTRIES 语句的表中的数据?
【发布时间】:2014-07-23 19:18:11
【问题描述】:

我需要将 BKPF 和 BSEG 表中的一些数据压缩到一个表中。例如,假设决赛桌必须看起来像这样:

| BKPF-BUKRS | BKPF-GJAHR | BKPF-MONAT | BSEG-DMBTR |
|============|============|============|============|
|         01 |       2014 |         02 |   1,751.55 |
|         01 |       2014 |         02 |     526.45 |
|         02 |       2014 |         02 |  32,112.01 |
|            |            |            |     ...... |
|============|============|============|============|

为了使程序高效,我想使用 FOR ALL ENTRIES 语句。所以它看起来像这样:

SELECT BUKRS BELNR GJAHR MONAT 
  FROM BKPF 
  INTO CORRESPONDING FIELDS OF TABLE IT_BKPF
  WHERE .... 

IF IT_BKPF IS NOT INITIAL. 
  SELECT DMBTR
    FROM BSEG 
    INTO CORRESPONDING FIELDS OF LS_BSEG 
    FOR ALL ENTRIES IN IT_BKPF 
    WHERE BUKRS = IT_BKPF-BUKRS AND 
          BELNR = IT_BKPF-BELNR AND 
          GJAHR = IT_BKPF-GJAHR. 

    LS_RESULT-BUKRS = LS_BSEG-BUKRS.
    LS_RESULT-GJAHR = LS_BSEG-GJAHR.
    LS_RESULT-MONAT = ???
    LS_RESULT-DMBTR = LS_BSEG-DMBTR.

    COLLECT LS_RESULT INTO IT_RESULT.
  ENDSELECT.
ENDIF.

现在的问题是:如何获取每个条目的 BKPF-MONAT 值?有没有办法对所有条目做到这一点?另一种解决方案是两个 SELECT 循环,例如:

SELECT BUKRS BELNR GJAHR MONAT 
  FROM BKPF 
  INTO CORRESPONDING FIELDS OF LS_BKPF
  WHERE .... 

  SELECT DMBTR
    FROM BSEG 
    INTO CORRESPONDING FIELDS OF LS_BSEG 
    WHERE BUKRS = LS_BKPF-BUKRS AND 
          BELNR = LS_BKPF-BELNR AND 
          GJAHR = LS_BKPF-GJAHR. 

    LS_RESULT-BUKRS = LS_BKPF-BUKRS.
    LS_RESULT-GJAHR = LS_BKPF-GJAHR.
    LS_RESULT-MONAT = LS_BKPF-MONAT.
    LS_RESULT-DMBTR = LS_BSEG-DMBTR.

    COLLECT LS_RESULT INTO IT_RESULT.
  ENDSELECT.
ENDSELECT.

但我认为这不是很有效.. 通常你会为此使用 JOIN,但 AFAIK 你不能使用集群表 (BSEG) 来做到这一点。

【问题讨论】:

  • 您确定使用FOR ALL ENTRIES 会使程序更高效吗?
  • @Jagger 如果你 FOR ALL ENTRIES-ing 所在的表是排序表类型,它会。
  • @RavenDreamer 我不太确定在这种情况下排序是否有帮助。看看这个 Open-SQL-Query 是如何实际转换为底层数据库的 SQL-Query 会很有趣。 Here 是一篇有趣的文章,它展示了 SQL Server 的外观。看起来有几个(取决于FOR ALL ENTRIES 表的大小)SELECT 创建和统一的语句,在这种情况下排序没有帮助。
  • @Jagger 不排序表,type 排序表。除非传递“排序表”类型,否则数据库无法知道任何给定参数是否已排序(这可以导致更快更有效的查询)。
  • @RavenDreamer 正如我所说,由于语句被转换为 DB SQL 的方式,它是哪种表并不重要。

标签: abap opensql


【解决方案1】:

尝试在SELECT. ENDSELECT 中读取来自IT_BKPF 的条目。

例如这样:

FIELD-SYMBOLS: <fs_str_bkpf> LIKE LINE OF it_bkpf.

SELECT.
...
  READ TABLE it_bkpf WITH KEY bukrs = ls_bseg-bukrs belnr = ls_bseg-belnr
    gjahr = ls_bseg-gjahr ASSIGNING <fs_str_bkpf>.
...
    ls_result-monat = <fs_str_bkpf>-monat.
ENDSELECT.

让表IT_BKPF 成为HASHED TABLE 或至少SORTED TABLE,那么您应该不会有更大的性能问题。

这是一些工作示例(忽略CLIENT SPECIFIED,我不得不使用它,因为我正在使用的客户端中没有数据)...

DATA: lt_bkpf TYPE HASHED TABLE OF bkpf
  WITH UNIQUE KEY mandt bukrs belnr gjahr.
DATA: ls_bseg TYPE bseg.
TYPES: BEGIN OF t_result,
  bukrs TYPE bkpf-bukrs,
  gjahr TYPE bkpf-gjahr,
  monat TYPE bkpf-monat,
  dmbtr TYPE bseg-dmbtr,
END OF t_result.
DATA: ls_result TYPE t_result.
DATA: lt_result LIKE TABLE OF ls_result.
FIELD-SYMBOLS: <fs_str_bkpf> LIKE LINE OF lt_bkpf.

SELECT mandt bukrs belnr gjahr monat
  UP TO 10 ROWS
  FROM bkpf CLIENT SPECIFIED
  INTO CORRESPONDING FIELDS OF TABLE lt_bkpf.

IF NOT lt_bkpf IS INITIAL.
  SELECT dmbtr
    FROM bseg CLIENT SPECIFIED
    INTO CORRESPONDING FIELDS OF ls_bseg
    FOR ALL ENTRIES IN lt_bkpf
    WHERE bukrs = lt_bkpf-bukrs AND
          belnr = lt_bkpf-belnr AND
          gjahr = lt_bkpf-gjahr AND
          mandt = lt_bkpf-mandt.

    MOVE-CORRESPONDING ls_bseg TO ls_result.
    READ TABLE lt_bkpf WITH KEY bukrs = ls_bseg-bukrs belnr = ls_bseg-belnr
      gjahr = ls_bseg-gjahr ASSIGNING <fs_str_bkpf>.

    ASSERT sy-subrc = 0 AND <fs_str_bkpf> IS ASSIGNED.

    ls_result-monat = <fs_str_bkpf>-monat.
    COLLECT ls_result INTO lt_result.
  ENDSELECT.
ENDIF.

【讨论】:

  • 我也想过这个问题,但担心额外读取表格会成为性能问题。正如您所说, HASHED 或 SORTED 语句应该可以解决问题。 Thanks alot!
猜你喜欢
  • 2021-12-24
  • 2016-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多