ABAP 中的 FOR ALL ENTRIES 非常方便,但是如果不正确使用它,也会产生很多问题:数据不一致、重复数据。
基础用法
当我们使用 SELECT 查询语句时,可以使用 FOR ALL ENTIRES, 并在 WHERE 条件中使用数据库表中一个或者多个字段。
IF gt_bseg[] IS NOT INITIAL.
SELECT prctr
ktext "利润中心描述
INTO CORRESPONDING FIELDS OF TABLE gt_cepct
FROM cepct
FOR ALL ENTRIES IN gt_bseg
WHERE prctr = gt_bseg-prctr
AND spras = sy-langu .
ENDIF.
如果表中只有少数的主键,我们可以选择这个方法。
但是如果一旦字段多了,这个方法可能就不适用了。
SELECT ryear
drcrk
rpmax
rtcur
racct
rbukrs
rcntr
kokrs
hsl01
hsl02
hsl03
hsl04
hsl05
hsl06
hsl07
hsl08
hsl09
hsl10
hsl11
hsl12
FROM faglflext
INTO TABLE lt_fagl
FOR ALL ENTRIES IN lt_skb1
WHERE ryear IN lr_gjahr
AND racct = lt_skb1-saknr
AND rbukrs = lt_skb1-bukrs.
由于这个查询没有所有的关键字段,当你试图将其与一些标准交易 FAGLB03 进行对账时,你会遇到问题。当你在不同时期使用相同的 CC 为相同的 GL 过账时,问题就会发生。在这种情况下,系统将只带来一个记录,而不是多个记录。另一方面,标准交易会让你得到的所有条目都有所不同。
当你调试 std 事务并到达 SELECT 时,你会想,这和我的查询一样。那为什么我的查询不工作呢?所以你从 ITAB 中下载数据--你的程序和 STD 事务。你将它们进行比较,你会注意到有几个条目肯定丢失了。经过几轮 VLOOKUP 和 excel 中的比较,你突然意识到 FOR ALL ENTRIES 丢了几个条目。这时,你已经是 Excel 的专家了。
为了解决这个问题,你会意识到你需要在 SELECT 中包含更多的关键字段。下一个障碍是向你的职能部门的同事和你的用户解释为什么它不能工作。
如果这个程序不是你开发的,我可以想象,当你意识到根本原因时,你有多恨那个人。一个愚蠢的错误! 从好的方面看,你现在是Excel专家了~
为什么需要主键
为了提高性能,你肯定希望在FOR ALL ENTIRES 的 ITAB 里有唯一的值。如果你不传递唯一的值,DB 将为每个重复的值重新选择记录。最后,DB 将删除重复的记录并给你结果集。
如果你在 SELECT 查询的选择字段中没有关键字段,那么这种去除重复的做法会造成数据不一致的情况。如果你认为你的所有字段都会构成唯一值,而不包括关键字段,你就会在将来招致麻烦。
添加表的键字段将确保所有选择的记录是唯一的。如果 SELECT 是一个联接,确保你包括联接中包括的所有表的所有关键字段。
TYPES:
BEGIN OF ty_t100,
arbgb TYPE t100-arbgb,
msgnr TYPE t100-msgnr,
text TYPE t100-text,
END OF ty_t100.
DATA: t_ids TYPE STANDARD TABLE OF t100-msgnr.
DATA: t_t100_all TYPE STANDARD TABLE OF t100.
DATA: t_t100 TYPE STANDARD TABLE OF ty_t100.
APPEND '001' TO t_ids.
APPEND '002' TO t_ids.
IF t_ids IS NOT INITIAL.
SELECT arbgb
msgnr
text "comment to see more records are dropping
INTO TABLE t_t100
FROM t100
FOR ALL ENTRIES IN t_ids
WHERE arbgb LIKE '0%'
AND msgnr = t_ids-TABLE_LINE.
WRITE: / 'Without All Key Fields', sy-dbcnt.
ENDIF.
如果你把第一个查询中的 TEXT 字段注释掉,你会看到更多的记录被丢弃。这是因为,DB 只保留唯一的记录。DB 会将整个记录与所有的记录进行比较,然后丢弃这些行。就像 DELETE ADJACENT DUPLICATES FROM itab COMPARING ALL FIELDS 。
总结
当你使用 FOR ALL ENTRIES 时,连同其他事情,你肯定想确保你在内部表中有所有的关键字段,你也在选择它们,以避免数据不一致。
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情