SAP ABAP语法实例(二)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
SAP ABAP语法实例
调试
1 调试键
F8跳过后面所有断点,程序执行完
2 外部、会话、调试断点
调试断点-debug时打的断点,程序远程完后就会消失
会话断点-程序运行前通过会话断点按钮打的断点,在同一登录会话不同窗口都有效,用户注销后消失
外部断点-程序运行前通过外部断点按钮打的断点,用户注销后再登录还是有效,但只针对同一用户有效
Select
SELECT <result> FROM <source> INTO <target> [WHERE <condition>] [GROUP BY <fields>] [HAVING <cond>] [ORDER BY <fields>].
GROUP BY:用于将一组数据条目压缩为一个单行作为选择最终结果;
HAVING:用于限定ORDER BY子句子数据目组的选择条件;
ORDER BY:用于限定行排序;
SELECT整体语法结构。
示例:
以上示例查询的是:20170503至20170510期间销售订单为JR01,且销售量大于50的单据的订单号、创建日期、创建者、类型以及合计销量,并按销售订单升序排序。
这里需要强调的是,如果要使用函数(如SUM、MAX、MIN),则需要将其他字段通过GROUP BY 进行分组。
如果需要继续对使用函数进行条件筛选,则可以使用关键字HAVING。
关键字ORDER BY 决定查询结果的排序方法,ASCENDING为升序,DESCENDING为降序。
1 SELECT SINGLE单行数据:
SELECT SINGLE <RESULT> INTO <target> FROM <source> ...
如果系统找到一个完全符合指定条件的行,SY-SUBRC返回0,否则返回4。
一般不需要指明所有字段,而是在SELECT后用"*"符号, 若指定多个数据对象,则需要将这些对象放在括号中,并用逗号隔开,而且其顺序需要与SELECT子句中指明的表字段顺序一致。
这里的<target>为结构非内表。
示例:
TABLES: sflight.
DATA: sum TYPE i VALUE 0.
SELECT SINGLE SUM( seatsocc ) INTO sum FROM sflight WHERE carrid ='LH'. WRITE:/ sum.
以上实现的是航线为LH的合计座位数。
区别以下代码,上面代码只输出一行,下面则输出多行:
2 SELECT / ENDSELECT循环
通过SELECT / ENDSELECT循环从数据库中读取多行。
SELECT [DISTINCT] <result>...<statement block> ENDSELECT.
注:使用DISTINCT自动去掉重复的行;SY-DBCNT(系统字段)为每次循环计数.
示例:
使用distinct达到的效果与select single一样,建议使用select single语句。
3 一次性SELECT ...INTO
一次性把数据选择到一个内表中去。
SELECT ...INTO|APPENDING[CORRESPONDING FIELDS OF]TABLE itab.
该情况下SELECT并不启动循环,因而不需要使用ENDSELECT语句;如果itab非空,则SELECT语句将用读取的数据覆盖其中的内容,使用APPENDING代替INTO将不覆盖内表,若结构不完全相同,也可使用CORRESPONDING FIELDS选项将同名区域相对应。
SQL编写注意事项-性能实例
1直接内表操作优先
尽量不要在频率较高的循环语句中使用update\insert\delete\modify等操作,即尽量不要通过工作区实现,直接通过操作内表实现。
示例:
2 select …into …table优于select…append table..endselect
在对内表赋值时,尽量使用select …into …table的写法来代替select…append table..endselect 的写法。
尽量用对内表的操作来代替对数据库的操作。
示例:
DATA: BEGIN OF it_mara OCCURS 0,
matnr LIKE mara-matnr,
maktx LIKE makt-maktx,
END OF it_mara.
第一种写法:
Select matnr
INTO it_mara
FROM mara.
APPEND it_mara.
ENDSelect.
第二种写法(high performace):
Select matnr
INTO TABLE it_mara
FROM mara.
3 使用for all entries
不推荐
Loop at int_cntry.
Select single * from zfligh into int_fligh where cntry = int_cntry-cntry. Append int_fligh.
Endloop.
推荐
Select * from zfligh appending table int_fligh
For all entries in int_cntry
Where cntry = int_cntry-cntry.
内表可以用来存放多笔数据,OPEN SQL允许以内表数据作为查询条件,以方便对查询对查询数据的进一步的筛选,相关语法如下:
Select <f1…fn> from <dbtab> FOR ALL ENTRIED IN <itab> WHERE …
需要注意的是,在FOR ALL ENTRIED IN itab 之前,一定要检查itab表是否为空,若为空则不执行查询,否则会查询所有非条件限制的数据。
示例1:
CHECK LT_MKPF[] IS NOT INITIAL.
* IF P_MATNR[] IS NOT INITIAL.
SELECT MBLNR ZEILE MJAHR BWART WERKS MATNR MENGE SHKZG FROM MSEG INTO CORRESPONDING FIELDS OF TABLE LT_MSEG
FOR ALL ENTRIES IN LT_MKPF
WHERE MBLNR = LT_MKPF-MBLNR
and MJAHR = LT_MKPF-MJAHR
and WERKS IN P_WERKS
AND MATNR IN P_MATNR
AND BWART IN P_BWART.
示例2:
DATA: BEGIN OF it_mara OCCURS 0,
matnr LIKE mara-matnr,
maktx LIKE makt-maktx,
END OF it_mara.
DATA: BEGIN OF it_makt OCCURS 0,
matnr LIKE mara-matnr,
maktx LIKE makt-maktx,
END OF it_makt.
第一种写法:(需定义it_mara)
Select matnr INTO TABLE it_mara FROM mara.
LOOP AT it_mara.
Select SINGLE maktx INTO it_mara-maktx FROM makt
Where matnr = it_mara-matnr AND spras = sy-langu.
MODIFY it_mara TRANSPORTING maktx. *只修改maktx字段ENDLOOP.
第二种写法(需定义it_mara &it_makt): ——high performace
Select matnr INTO TABLE it_mara FROM mara.
Select matnr maktx INTO TABLE it_makt FROM makt
FOR ALL ENTRIES IN it_mara
Where matnr = it_mara-matnr and spras = sy-langu.
4 where…in…
对存在OR条件等判断的语句,尽量使用IN来代替。
5 where条件
●Where 语句中尽量避免使用”<” ”>”等模糊条件来查询。
●不要使用CHECK语句对table 进行条件查询,用where语句代替。
6 Join语句连接
多个表数据查询尽量使用JOIN语句,且注意应选择数据量最小的表来作为基表,尽量避免三个以上的表的相关JOIN查询。
7 select single
在查询单条语句时,尽量使用select single语句,不要使用select…endselect语句。
8 Up to n rows
使用语法up to n rows来实现对数据前n项的查询。
9 Select 栏位尽量具体
尽量使用select f1 f2…具体栏位来代替select * 写法。
10利用函数
充分利用系统提供的标准函数,如max,min,avg,sum,count.
示例(使用max聚合函数):
不推荐
Maxnu = 0.
Select * from zflight where airln = ‘LF’ and cntry = ‘IN’.
Check zflight-fligh > maxnu.
Maxnu = zflight-fligh.
Endselect.
推荐
Select max( fligh ) from zflight into maxnu where airln = ‘LF’ and cntry = ‘IN’. 11使用INTO table 代替select endselect
不推荐
Refresh: int_fligh.
Select * from zflight into int_fligh.
Append int_fligh. Clear int_fligh.
Endselect.
推荐
Refresh: int_fligh.
Select * from zflight into table int_fligh.
TABLE
1 RANGE TABLE
Range Table 为SAP R/3系统标准内表的一种,结构与Selection Table 一致,由SIGN, OPTION, LOW 和HIGH字段组成;
可以通过TYPE RANGE OF 语句或RANGES 关键字定义Range T able。
1) TYPE RANGE OF…
DATA rtab {TYPE RANGE OF type}|{LIKE RANGE OF dobj}
[INITIAL SIZE n]
[WITH HEADER LINE]
[VALUE IS INITIAL]
[READ-ONLY].
示例:
2) RANGES
语法:
RANGES rtab FOR dobj [OCCURS n].
示例:
2 两个内表间赋值
●Itab1[]=itab2[]
示例:
tables: zcustom,scustom.
data t1_zcustom type STANDARD TABLE OF zcustom with HEADER LINE.
data t2_zcustom like STANDARD TABLE OF zcustom WITH HEADER LINE.
select * from scustom into CORRESPONDING FIELDS OF TABLE t1_zcustom.
t2_zcustom[] = t1_zcustom[].
●APPEND lines of itab2 to itab1(append itab2 to itab1)
Itab2 to itab1 还可通过LOOP 语句循环读取内表实现。
示例1:
loop at t1_zcustom.
append t1_zcustom to t2_zcustom.或append lines of t1_zcustom to t2_zcustom. endloop.
以上LOOP循环虽可实现内表逐行添加,但建议使用批量增加代替逐行添加:
不推荐
Loop at int_fligh1.
Append int_fligh1 to int_fligh2.
Endloop.
推荐
Append lines of int_fligh1 to int_fligh2.
示例2:
DATA: begin of it_makt/it_mara OCCURS 0 ,
…
END OF it_makt/it_mara .
select matnr maktx from MAKT INTO TABLE it_makt Where spras = sy-langu. append LINES OF it_makt to it_mara.
-------------------------------------------------------------------------------------- TABLES: MARA.
DATA LT_MARA LIKE STANDARD TABLE OF MARA WITH HEADER LINE.
DATA LT2_MARA LIKE TABLE OF LT_MARA WITH HEADER LINE.
SELECT * FROM MARA INTO TABLE LT_MARA.
APPEND LINES OF LT_MARA TO LT2_MARA.
与上面仅内表定义不同。
3 COLLECT
Collect语句可根据某些关键列来完成数值字段的汇总。
COLLECT一般在loop中使用,使用collect不需要对内表排序,对内表也没有其他限制条件。
语法如下:
COLLECT itab1 INTO itab2
其中itab2 必须定义为哈希表,并指定1个或多个关键字段。
示例如下,数值字段有两个,非数值字段也有两个且定义为KEY ,经过下面结果可以看到,事实上完成了一个物料+库位的一个分类汇总:
tables: mkpf,mseg.
data: begin of ita,
mblnr type mseg-mblnr,
lgort type mseg-lgort,
menge type mseg-menge,
dmbtr type mseg-dmbtr,
end of ita .
data: itb like ita OCCURS 0 WITH HEADER LINE .
data: itc like HASHED TABLE OF ita with UNIQUE KEY mblnr lgort WITH HEAD ER LINE. "定义统计结果内表(必须是哈希内表)
SELECT * FROM MSEG INTO CORRESPONDING FIELDS OF TABLE itb
WHERE mblnr BETWEEN '4903037513' AND '4903037514'.
loop at itb.
collect itb into itc. "按关键列统计值
endloop .
write : sy-uline .
write : '内表数据:' .
loop at itb.
write : / ' ' ,itb-mblnr,itb-lgort, itb-menge,itb-dmbtr.
endloop .
write : sy-uline .
write : 'collect后的数据:' .
loop at itc.
write : / ' ' ,itc-mblnr,itc-lgort, itc-menge,itc-dmbtr.
endloop .
write : sy-uline .
实现的功能是根据物料凭证号+库位来统计移动数量及金额,从结果来看应该是正确的,因为上面凭证是311从7012和7018的移库,数量肯定相等,金额为0,下面凭证为261发货。
4 内表、字符串及循环处理
●LOOP循环内表时,可根据需求加上where条件.
●读取内表时加上扩展语句BINARY SEARCH.
●内表数据增加
APPEND ITAB(带表头).或APPEND WA TO ITAB(不带表头).
●内表数据更新
MODIFY 更新内表时,加上transponding 可以指定更新字段。
示例如下:
tables: zcustom,scustom.
data t1_zcustom like zcustom OCCURS 0 WITH HEADER LINE.
select * from scustom into CORRESPONDING FIELDS OF table t1_zcustom .
loop at t1_zcustom .
t1_zcustom-name = 'OK1'.
t1_zcustom-city = 'OK2'.
MODIFY T1_ZCUSTOM TRANSPONDING NAME.
endloop.
“只更新了name字段。
如去掉transponding则内表更新name和city字段。
. 性能实例
1 使用二分法查询,提高查询/读取内表数据速度
不推荐
Read table int_fligh with key airln = ‘LF’.
推荐(使用前先按关键字排序)
Read table int_fligh with key airln = ‘LF’ binary search.
2使用批量修改内表代替逐行修改
不推荐
Loop at int_fligh.
If int_fligh-flag is initial.
Int_fligh-flag = ‘X’.
Endif.
Modify int_fligh.
Endloop.
推荐
Int_fligh-flag = ‘X’.
Modify int_fligh transporting flag where flag is initial.
.。