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
的时候,取出的字段一定要包括表的主键
,这样就没有问题了。