目标及说明
目标:
- 熟悉掌握ABAP程序的调试方法和技巧
- 熟悉掌握断点的设置和调试运行的使用
- 熟悉掌握检查点的应用
- 熟悉掌握程序跟踪的方法和技巧
实践说明:
- 通过使用ABAP的跟踪调试技术,检查ABAP程序是否按照功能需求运行;
- 跟踪程序运行时数据的读取情况,以及程序运行性能分析。
实践7-调试跟踪《实践4A4-筛选符合条件的订单输出明细》
调试跟踪场景:
在《实践4A4-筛选符合条件的订单输出明细》,希望通过跟踪了解如下信息:
- 当初始界面输入条件并执行后,从数据读取到内表的记录有哪些,具体值是什么?
- 读取记录后,订单明细中物料的名称和销售金额是否按代码获得了?
- 对指定订单的销售总金额进行更改后输出。
- 跟踪程序在执行时数据的读取过程,了解程序执行过程中不同项目所消耗的时间。
实践步骤:
本实践将对已完成的《实践4A4-筛选符合条件的订单输出明细》进行调试,以确保程序满足功能需求。
No | 部分 | 说明 |
---|---|---|
1 | 设置断点 | 通过SE38程序编辑器查看程序并设置会话断点,以让程序在运行 |
2 | 程序调试 | 程序运行到指定断点后,将调出调试界面,由此可掌握程序执行的过程 |
2.1 | 调试运行及查看变量 | 当程序运行到指定断点后,查看指定变量的值 |
2.2 | 设置和使用监控点 | 使用监控点,如此当指定变量在满足指定条件时,程序将会暂停,由此可以对变量的数据进行检查 |
2.3 | 增加临时断点 | 在调试其中增加断点,以运行到指定语句时临时暂停,此类断点在退出程序调试后则会失效 |
2.4 | 修改运行值 | 在程序调试过程中,对指定变量的值进行修改,将会影响后续的数据。 |
3 | 程序跟踪 | 获得程序运行过程中的具体情况 |
3.1 | ST03性能跟踪 | 详细获得SQL语句、内存、RFC调用的执行情况,包括获得的记录、消耗的时间等 |
3.2 | SE30运行分析 | 获得程序运行过程中不同部分,包括内部过程代码(函数、子程序、方法、模块等)、内部数据获取(表缓存、内表数据处理等)、外部数据获取(连接数据库表、获得记录等)、杂项(屏幕、事务代码调用等)的运行时间。 |
1、设置断点
使用程序编辑器查看程序,找到如下几行代码:
SELECT oh~orderid oh~orderdate oh~customerid
……
IF order_i_stru-orderid <> prev_orderid.
……
IF cnt > 1.
然后鼠标点击如上代码行前面的空白列处,则将添加会话断点;或可将鼠标点选到指定代码行的任一位置后点击“会话断点”图标 ,效果一样,如图7-1所示。
2、程序调试
在ABAP编辑器界面点击“直接处理”按钮,以运行此程序,在如图7-2所示的初始界面中输入客户编号“C10002”后,点击执行,程序将根据断点的设置情况,打开如图7-3所示ABAP调试器界面,并运行到第一个断点所在的“Select……”语句中暂停等待用户操作。
1)调试运行及查看变量值
点击“单步运行”按钮或功能键F5,将会运行到下一个语句“LOOP AT……”中暂停并等待用户操作,如图7-4所示。
双击此语句中的“order_i_itab”或直接在右下角界面的变量列中输入,可查看到值中内容为“ [15x18(524)] ……”(如图7-5所示),如此表示在“SELECT……”语句执行后内表“order_i_itab”中包含了15行18列的记录。
双击变量“order_i_itab”后,界面跳转到表页签,并显示此内表的记录如图7-6所示。
滚动表内容到最右边,可看到物料名称(MATERIALNAME)、金额(IAMOUNT)处的值为空,如图7-7所示。
2)设置和使用监控点
点击应用工具栏中的监控点按钮,在弹出的界面(图7-8所示)中输入变量以及在可用条件条目中输入“= '1076'”,然后点击对勾,由此创建了一个监控点。在此界面中,可以点击“可用条件条目”左边的按钮,可查看到条件的输入帮助;还可点击传输按钮,将当前设置的监控点添加到“调试器的监控点对象”中并继续添加监控点。
切换到“断点/监控点”页签下的“监控点”,可查看到刚才已添加的监控点及其条件,如图7-9。
点击应用工具栏的“继续”按钮或功能键F8,程序将继续运行,并当物料编号(MATERIALID)等于“1076”时暂停等待用户操作,此时再查看“order_i_itab”记录,可看到物料编号为“1076”对应记录前的记录,物料名称和金额已更新,如图7-10。
3)设置临时断点(调试器断点)
点击应用工具栏的创建断点按钮,将显示如图7-11所示界面,在此可对指定的关键字或方法、函数等对应的语句前增加临时断点,按图示输入后点击对勾,设置临时断点后效果如图7-12所示。
在“断点/监控点”页签的“断点”中,可看到添加的“调试器断点”如图所示。
断点设置后可对程序继续运行以并查看各变量的数据变化情况,或不需要时将这两个临时断点删除;此类临时断点也可在代码行前的空白处点击启用,在程序调试后将失效。
4)修改运行值
继续运行程序,直到运行到“END-OF-SELECTION”事件后的IF 处,如图7-14。
双击oamount到变量窗口,再双击变量中的“oamount”,将显示“详细显示”页签,可看到视图下的值为0,点击铅笔按钮,如图修改为“1000”后回车,如图7-15。
继续运行,将把结果输出到界面中,可看到最后订单的订单金额按修改后的“1000”输出了。
3、程序跟踪
SAP提供了不少的程序跟踪(Trace)功能,以让开发或测试人员等了解程序在执行的过程中是如何的:读取了哪个表、读取了哪些数据、花了多长时间等等。
如下分别通过ST05(性能跟踪)和SE30(程序跟踪)对《实践4A4-筛选符合条件的订单输出明细》进行跟踪。
1)ST05性能跟踪
执行事务代码ST05后,将显示如图7-17所示界面,可从跟踪类型(Trace Type)中勾选对应类型后,则将启用指定的跟踪,包括SQL的跟踪、缓存的跟踪、RFC的跟踪等等,本实践勾选“SQL Trace”。
在工具栏中点击以通过选择指定的程序进行跟踪,否则将对整个系统的所有程序进行跟踪,在弹出的窗口中选择和输入如图7-18,输入后对勾,由此激活了跟踪。
运行程序,在初始界面中输入客户编号范围为“C10001~C10005”,如图7-19所示,输入后点击执行按钮,则将输出相应的订单信息。
回到ST05界面中,点击工具栏的按钮以停止对程序的跟踪,然后再点击按钮以查看跟踪内容,点击后显示界面如图7-20所示,可以对跟踪的情况筛选后输出。
在界面中可以保持不变,点击执行按钮,将显示内容如图所示,从图7-21中可看出从什么时间执行,执行SQL语句时花了多长时间、影响到多少条记录、是哪个程序在执行的、相应的表是哪个、语句是什么等等。
双击其中一条木的Statement,可看到在执行时的详细语句,显示如图7-22。
2)SE30运行分析
运行SE30后,将显示如图7-23所示界面,可在“Program”中输入你的程序名称后,点击执行按钮。
在执行程序后的初始界面中,输入客户编号范围为“C10001~C10005”后点击执行按钮,将输出结果,然后点击2次系统工具栏的返回按钮,将显示运行结果界面如图7-24所示。
双击其中节点(如“DB:Open” )可看到具体项目的跟踪情况,如图所示。
图中:
从记录可看到,连接次数和运行时间最多的是ZTMATERIAL对应的记录,而对比本程序的代码,连接ZTMATERIAL是为了获得物料的名称,也即表示获得物料名称所需要的时间是最多的。如果要优化代码,则可以从获得物料名称语句着手,看看有没优化的空间,在此不详述。
点击界面中的按钮,可以获得性能优化的提示和帮助,点击后显示如图7-26,可从中选择项目双击查看示例,并通过点击“测量运行时间”按钮,可看到不同代码下的运行时间(以微妙计算)。
由图中可看到,实现相同的得到最大消息编号(MSGNR),使用Select…Where+Check语句需要4790微妙,而使用aggregate function(聚合函数)语句,只需要553微妙,相差近10倍的时间。因此,考虑性能,肯定优先使用聚合函数,而不使用Select…Where+Check。
其他不同项目的提示和帮助可展开查看和测试。
本实践小结:程序跟踪及调试
ABAP调试器是一个非常有用的工具,包括在程序开发的过程中及完成后,熟悉掌握和善用此工具,对程序进行调试,将尽可能在程序交付前发现和解决问题,如此提升程序的质量以及提高开发的效率。
1、程序调试器
1)断点类型
2)运行按键
3)调试器页签页
界面显示类标签
变量跟踪类标签
其他类标签:
2、SQL执行时间和优化
对于程序的执行,肯定是希望执行的越快越好,如果要输出一张报表需要几十秒甚至几分钟,那么对于用户来说是很差的体验。从如上SQL的语法看,要读取记录,可有多种方式,如表数据可以通过多表连接、子查询,WHERE条件可以一般条件也可以ALL ENTRIES IN……,如果数据库表记录不多,只要能获得准确的记录,用不同的语句都没问题;而对于上规模的企业,数据量非常巨大,此时则要尽可能用最优的SQL语句以提高效率。如下从获得SQL操作时间和优化两方面进行说明。
1)操作时间
可以通过记录SQL执行前和执行后的时间后,取的差异值作为SQL的执行时间。
DATA t TYPE i. “定义类型为i的变量t
GET RUN TIME FIELD t. “获得当前时间(到秒)后存储于t
2)SQL优化
- 优先使用ABAP字典的视图,以能使用缓存;其次使用Join多表联合查询;如ABAP字典和Join都不能满足,再考虑ALL ENTRIES IN;不得已的情况下才使用子查询;
- 尽可能使用游标读取数据,如此省掉从数据库中读取记录并INTO到内表的资源消耗;
- 在INSERT、UPDATE、DELETE时,使用内表的方式操作,以减少与数据库交互次数;
- 在需要经常访问的字段上创建索引,并且将重复数据最少的字段放在索引最开头的规则来确定索引中字段顺序;要在重复率少的字段上创建索引,而不应该在重复率高的字段上创建索引;对经常读取的表创建索引,而需要经常更新的表,则不适合创建索引,如果创建了索引在数据更新时会更新索引;创建索引时不要多于4个字段,一个表上创建的索引不要超过5个;
- 尽量不要将允许为NULL值的字段作为索引字段,因为某些数据库不会将NULL值存储到索引表中;
- 避免全表扫描,尽可能在条件语句中使用索引字段进行查询;如果组成索引的所有字段都用到,并且使用的是“=”表达式,同时各个表达式使用“AND”连接时,查找效率会最高;
- 在条件语句中,要将索引字段条件写在最前面(左边),非索引字段写在最后面,如此查询效率也会高些;
- 如果一个索引由多个字段组成,在只选择索引的部分字段来进行查询时,也可以使用到索引,但使用时需要注意按照索引定义的顺序来使用:如表中创建了 a,b,c,d,e 五个字段组成的索引,当使用c,d作为条件来查询时,查询条件前面也一定要带上a,b查询条件字段,如果只选择c,d两个字段,是用不到索引的;
- 在条件中尽量不要使用否定的逻辑表达式,如NE(<>)、 NOT LIKE,如此使用时不会使用索引,所以尽量使用肯定的逻辑表达式,如EQ、LIKE;
- 尽量不要使用OR来连接多个索引字段表达式,OR后面的表达式中的字段将不会用到索引,可以看能否使用IN操作符实现;
- 一般情况下不要使用ORDER BY,除非ORDER BY所使用的索引与WHERE语句所使用的索引一样。