R/3 ABAP开发学习笔记

时间:2021-01-19 16:37:08

T-Code:ST05,SE38,SE37,SE93,SE73,ABAPhelp

           1、ST05是用于在开发ABAP程序时,对应事务码取得的字段是“数据结构”而不是“透明表”的时候,通过ST05的“SQL跟踪”来获得相关“Select”的语句;一般查看“REC”列耗时比较多的“Select”语句;
           2、跟踪时如果有涉及到“数量”这类有对数据表进行更新或插入操作的,则直接去查Update和Insert的SQL语句;
           3、在跟踪后,直接双击“对象名”列的名称,点选“表格字段”转到“SE11”的表字段表;
           4、ABAP程序开头的Tables:“数据表名”,只有在屏幕中有用到的表,才需要声明;在程序中用到的表则不需要进行在Tables内声名;
           5、抓SAP“文本”字段的数据,要先自定义变量,然后通过SE37的函数“FUNCTION ’ZREAD_TEXT’”取回文本数据;
           6、新建的ABAP程序,在测试运行的时候要先进行“激活”,才能测试运行;
           7、SE93:把ABAP写好的程序指定一个事务码执行;
           8、abap引号内的字符’’必须要是大写;
           9、ABAP select 里面的语句,不能像mssql有那么丰富的函数使用,需要导到内表后再对数据进行操作;
           10、’EQ’是单个数据值,’BT’是between区间的意思。
           11、在写select inner join 里面,要注意是否需要加上销售组织的条件;on 条件1 and 销售组织条件。
           12、SELECTION-SCREEN,里面有两个子项,PARAMETERS和select-options。
                   PARAMETERS一般是用于必输项的屏幕参数设置,如果这个参数不是必输项的,就要用select-options。
                   在select ...where条件里,用PARAMETERS的条件语法是“数据字段 = 屏幕字段”;
                   而select-options的条件语法是“数据字段 in 屏幕字段”。
           13、在where判断一个日期型数据是空,不是DEAKT = ’’,也不是DEAKT is initial,而应该写成DEAKT = ’00000000’ (8个0)。
           14、一对多的inner join,如果取出的数据有重复,前面加上distinct,用法和MSSQL相同。

           15、sy-subrc,指上一个语句执行是否成功;执行成功返回0,执行不成功返回非0。用if判断。

            16、如果一个语句中,该名称同时可能代表内表或者同名表工作区,则需要在内表名称之后加“[]”指明当前操作的是内表对象。不提倡使用带有表头行的内表,而是应该总是声明结构相同的其他数据对象作为显示工作区进行内表行操作。

如何调整ABAP程序的性能(copy)
1、使用where语句 
不推荐
Select * from zflight.
Check : zflight-airln = ‘LF’ and zflight-fligh = ‘BW222’.
Endselect.
推荐
Select * from zflight where airln = ‘LF’ and fligh = ‘222’.
Endselect.
2、使用聚合函数
不推荐
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’.

3、使用视图代替基本表查询
不推荐
Select * from zcntry where cntry like ‘IN%’. 

Select single * from zflight where cntry = zcntry-cntry and airln = ‘LF’.
Endselect.
推荐
Select * from zcnfl where cntry like ‘IN%’ and airln = ‘LF’.
Endselect.

4、使用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.

5、使用批量修改内表代替逐行修改
不推荐
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.

6、使用二分法查询,提高查询内表数据速度
不推荐
Read table int_fligh with key airln = ‘LF’.
推荐
Read table int_fligh with key airln = ‘LF’ binary search.

7、两个内表添加使用批量增加代替逐行
不推荐
Loop at int_fligh1.
Append int_fligh1 to int_fligh2.
Endloop.
推荐
Append lines of int_fligh1 to int_fligh2.

8、使用table buffering
Use of buffered tables is recommended to improve the performance considerably. The buffer is bypassed while using the following statementsSelect distinct 
Select … for update 
Order by, group by, having clause 
Joins 
Use the Bypass buffer addition to the select clause in order to explicitly bypass the buffer while selecting the data.

9、 使用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.

10、正确地使用where语句,使查询能使用索引When a base table has multiple indices, the where clause should be in the order of the index, either a primary or a secondary index
To choose an index, the optimizer checks the field names specified in the where clause and then uses an index that has the same order of the fields. One more tip is that if a table begins with MANDT, while an index does not, there is a high possibility that the optimizer might not use that index.

11、正确地使用MOVE语句
Instead of using the move-corresponding clause it is advisable to use the move statement instead. Attempt should be made to move entire internal table headers in a single shot, rather than moving the fields one by one.

12、正确地使用inner join
Let us take an example of 2 tables, zairln and zflight. The table zairln has the field airln, which is the airline code and the field lnnam, which is the name of the airline. The table zflight has the field airln, the airline code and other fields which hold the details of the flights that an airline operates.

Since these 2 tables a re logically joined by the airln field, it is advisable to use the inner join.
Select a~airln a~lnnam b~fligh b~cntry into table int_airdet
From zairln as a inner join zflight as b on a~airln = b~airln.
In order to restrict the data as per the selection criteria, a where clause can be added to the above inner join.

13、使用sort by 代替order by

14、避免使用SELECT DISTINCT语句
使用的 ABAP SORT + DELETE ADJACENT DUPLICATES 代替.

定义内表与工作区最方便的方法

*定义 名为 ITAB 的内表, 内表结构 参照表 TABLE 。

DATA: ITAB TYPE TABLE OF TABLE. 

*定义 名为 WA 的工作区, 其 行结构与 内表 ITAB 相同 。

DATA: WA LIKE LINE OF ITAB. 

----------------------------------------------------------------

       1.使用occurs 0,定义的不再是对象,而是internal table 
       2.使用with header line后缀,定义为internal table的同时也定义了一个同名对象,因此可以用以下语句: 
LOOP AT STH. 
WRITE: / STH. 
ENDLOOP. 
3.TYPE后面接结构,LIKE后面接对象 
4.OBLIGATORY为必输字段 
5.DATA SEPARATER . = DATA SEPARATER TYPE C.
6.关于内表的结构描述,它的当前记录数据是放在header line中的,Occurs 是分配数据缓冲区,大小不重要,系统会自动分配。但定义内表不用occurs就需要用with header line,occurs语句记得是为了向下兼容。
7.occurs 指明的數量是有一點學問的. 
1.當你知道可能每次用Select命中或交換的紀錄數xxx時,可指明 occurs xxx. 
2.如用occurs 0 聲明時, buffers 由系統自動分配. 
8.SELECT在into时记得一般都要加上table,不然是into一个工作区,即wa,而工作区要写入内表,则需要再append,所以直接定放内表即可,内表和工作区的区别就在于工作区就相当于表头,是有一行,data定义begin of itab时不加occurs就是工作区,加了就是内表,occurs *,后面表示系统初始分配给此内表多少行,每次满时再多分配多少行,我们平常为了节约内存,一般直接用0,with header line是为了定义含表头的内表,平常occurs就直接带表头,而with header line一般是在itab1 like itab occurs 0 with header line时用,这是参照一个内表定义另一内表,如果要带表头,一定要加with header line。 
你这样问不是办法,最好不懂时直接接F1,查到SAP的帮助即可. check是检查后面的逻缉是否满足,不满足则在上例是跳出form,不的执行下面的语句。 

说实在,初略的看了一下上面的程序,写得太烂了,竟然将usr01或usr03透明表中的字段按条件取到一个表工作区,竟然不加single,象这种不加single的select按理说应该是调不过的,必须在后面再对应一个endselect,而这种select加endselect用每次去读一次透明表,访问数据库的次数太多了,换个好一点程序自己研究吧。