For all entries使用中注意的问题

For all entries使用中注意的问题
对于不能 join 的表,使用 for all entries in 语句将该表与内表串联。
SELECT bseg~kunnr
       bseg~lifnr     
       bseg~belnr
INTO TABLE itab_bseg
FROM bseg
   FOR ALL ENTRIES IN itab_main
WHERE bukrs in _bukrs
and ( belnr = itab_main-belnr
    AND hkont = itab_main-hkont ).
由于 BSEG 不能和 BSIS inner join 所以先将 BSIS 内容放到 itab_main 中,然后用 FOR ALL ENTRIES IN 来串联。
1-WHERE 子句中的 bukrs in _bukrs 是指 bseg-bukrs 存在于 _bukrs 这个 select-options 中, _bukrs 不是 itab_main field 所以这部分不包括在括号中 .
当然会增加内存使用了。
原本一个条件,数次(驱动表的纪录条数)向对 DB 操作,
使用了 FOR ALL ENTRIES 后,
相当于把驱动表里的条件字段的所有值用 OR 连起来,
一次对 DB 操作,
条件语句增大,势必使内存占用增多。
 
1 SELECT CARRID
         CONNID
         PRICE
    FROM SFLIGHT
    INTO TABLE IT_PRICE
     FOR ALL ENTRIES IN IT_SFLIGHT
   WHERE CARRID = IT_SFLIGHT-CARRID
     AND CONNID = IT_SFLIGHT-CONNID'.
WHERE 条件中, IT_SFLIGHT-CARRID IT_SFLIGHT-CONNID 这些列将用作占位符。该 SELECT 语句的结果集是 SELECT 语句的所有结果集的联合,这些结果集是用内部表 IT_SFLIGHT 中的相应值在每一行上替换占位符的结果。实际上该 WHERE 子句的特殊变式就是下面 WHERE 基本语句的简略写法。
SELECT DISTINCT CARRID
                  CONNID
                  PRICE
    FROM SFLIGHT
    INTO TABLE IT_PRICE
   WHERE ( CARRID = 'LH'   AND
           CONNID = '2415' ) OR
         ( CARRID = 'SQ'   AND
           CONNID = '0026' ) OR
         ( CARRID = 'LH'   AND
           CONNID = '0400' ) .
2 使用该语句,对于最后得出的结果集系统会自动删除重复行。因此如果你要保留重复行记录时,记得在 SELECT 语句中添加足够键值项目(有必要时,增加全部键值项目),以保证结果集中所需重复项目不会被删除。(例如选取支付金额时,支付事件可能不同,但金额可能相同,此时一定要注意,以避免错误删除结果记录。)
3 FOR ALL ENTRIES IN 后面使用的内部表 itab 如果为空,系统将视为无条件选取,将当前 CLIENT 下所有记录选出 。因此为避免无意义的全件检索,在使用该语句前一定要判断内部表 itab 是否为空,为空时不执行包含该语句的数据库检索处理。
4 .由于 itab-f 实际上是作为占位符被替换,所以内部表 itab 中不要包含 HEADER 行(项目标识名称行),以免造成混淆,检索出错。
5 .内部表 itab 中作为条件替换用项目的类型和长度,一定要和检索数据库中对应的项目相同,否则编译不能通过。
6 .对于内部表 itab 中作为条件替换用项目,不能使用 LIKE,BETWEEN,IN 比较操作符 。因为这些比较操作符都是不确定比较操作符(将选择条件设定在一个范围内),而 FOR ALL ENTRIES IN 语句的作用相当于将选择条件块全部并列开来,用 OR 连接,如果每个 OR 分支中又是不确定的范围,那么系统性能将大大降低 ,因此 R/3 系统在使用该语句时禁止使用不确定比较操作符。
7 .使用该语句时, ORDER BY 语句和 HAVING 语句将不能使用。
8 .使用该语句时,除 COUNT( * ) 以外的所有合计函数( MAX,MIN,AVG,SUM )都不能使用。
// 判断内表是否为空
使用语句: DESCRIBE TABLE ITAB LINES VARIABLE. 判断系统变量 sy-subrc 是否为 0 ,如果为 0 就表示不空,反之为空!
DESCRIBE TABLE ITAB LINES VARIABLE
IF NOT P_VARIANT IS INITIAL.
   
WX_VARIANT-VARIANT = P_VARIANT.
-------------------------------------------------------------------------
 
一、 Select 语句中使用 FOR ALL ENTRIES IN 需要注意的问题
ABAP 编程中 使用 for all entries in 是必不可少的语句 相信大家都使用过 例如
data: begin of ig_bseg occurs 0,
          werks like bseg-werks,
          belnr  like bseg-belnr,
          gjahr  like bseg-gjahr,
          dmbtr like bseg-dmbtr,
        end of ig_mseg.
if not ig_bkpf[] is initial.
  select werks belnr gjahr dmbtr into corresponding fields of table ig_bseg
  from bseg for all entries in ig_bkpf
  where werks = ig_bkpf-werks and belnr = ig_bkpf-belnr and  gjahr = ig_bkpf-gjahr.
endif.


需要注意以下问题
1
、首先,必须要判断 For all entries in 后面的内表是否为空,如果它为空的话,那么在 where 条件中的与内表中字段进行比较的结果全部为真 ,也就是全部满足条件,这会导致取出非常多的数据,极大地影响系统的性能。
2
、对于上例,按照逻辑分析可以取出某个凭证的所有行项目,但是实际情况会与你预期的不一致,如果某个凭证的多个行项目的 dmbtr 值是完全一样的,那么在内表 ig_bseg 中你只会得到一行记录,而不是多行,它自动使用了 distinct ,或者说删除了重复的行,这是个非常致命的问题,会导致你的程序逻辑错误,而且很难以查找 ,解决的办法就是要保证内表 ig_bseg 中取出的数据必须要有主键字段,在本例中,需要再添加 buzei 字段。

二、自建表和从系统外导入数据需要注意的问题
1
、自建表中建立文本类型的字段(自己创建 domain )时,需要注意是否允许字段可以保留文本的大小写状态,否则默认会全部转换为大写字母。
2
对于各种凭证编码字段,如:物料凭证 mblnr kunnr lifnr belnr, 在导入数据到自建表中时,一定要注意前导 0 的补充问题 ,否则导入的数据可能没有前导 0 ,补充前导 0 的函数为 CONVERSION_EXIT_ALPHA_INPUT ,另外,在建立自建表时,将该字段对应的 domain Convers. routine :设置为 ALPHA
 
补充,就是觉得这个用于数据少的内表合适,虽然是说一下子从数据库里拿数据,连接数据库次数少了,可是对数据库造成的负担较大。
 ----------------------------------------------------
 
Duplicates are discarded from the result set. If the internal table itab does not contain any entries, the system treats the statement as though there were no WHERE cond condition, and selects all records.
使用 FOR ALL ENTRIES 的时候,取出的字段一定要包括表的主键 ,这样就没有问题了。
 

你可能感兴趣的:(职场,for,休闲,all,entries)