ABAP Code Inspector 是每一位 ABAP 开发人员工具箱里必备的代码检测工具之一。使用 ABAP Code Inspector 自带的标准检查项,可以帮助开发人员快速检测 ABAP 代码中潜在的缺陷,提高代码质量,改善代码运行性能。
本文分享笔者从事 ABAP 应用程序开发十余年来在工作中积累的一些 ABAP Code Inspector 的使用经验。
我们可以在ABAP Code Inspector的检查变体(Check Variant)里,根据自己的需要灵活地选择对ABAP代码进行哪种类型的扫描动作。
下图是一个例子,意思是对ABAP代码中所有对数据库表产生了读写访问之处,进行 Table Names from SELECT Statements 的扫描。该扫描的具体行为,可以点击蓝底白色的感叹号图片,以获得帮助文档。下图这个例子里勾取的选项,意思是检查被访问的数据库表,在SE11的ABAP字段里的Technical Settings是否正确被维护了,比如表的缓存类型是否设置正确。
性能检查
Select-Statement can be transformed. X% of fields used - 检查内表字段的使用率
假设我们使用 SELECT *
从一张表里读取数据到ABAP内表,然后在后续代码中只使用到了A个字段,而读取的表在SE11里总共有B个字段,那么A除以B的结果越小,说明读出来的内表字段使用率越低。
也就是说,你或许该考虑只SELECT真正需要的字段来替代SELECT *? 只需要在上图设置里维护一个最低阀值,当Code Inspector扫描代码时,一旦检测到使用率低于维护的阀值就会报错。上图的20意思是20%.
Search DB Operations in loops across modularization units
Jerry 2007年刚加入SAP开始学习ABAP编程时,前辈们就告诫过我,不要在LOOP里使用SELECT语句,这样会极大影响代码的性能。
上图是通过Code Inspector扫描出来的一个例子,在双重LOOP循环里使用SELECT读取数据库表CRMD_DPP_HI_BLCK.
Nested Loops - 嵌套循环的检测
尽管当应用代码里嵌套循环的循环次数不大时,对代码运行的绝对时间没有太大影响——然而编写具有至少指数级时间复杂度的代码,在任何上下文里都不是一个好的编程习惯。
这个设置能够帮助我们快速找到所有的嵌套循环。
Copy current table row for LOOP AT
找出所有LOOP AT … INTO之处,理论上这些地方都可以用LOOP AT … REFERENCE INTO或者ASSIGNING 替换。当内表的行结构体字段很多时,使用后两种方式可以获得一些性能的提升。
Low-Perform. Parameter Transfers - 检测所有参数传递使用"Pass by Value"之处
编程语言里参数传递的 传引用
和 传值
这两种方式的辨析,至今仍然是很多互联网公司的面试题之一。
这个选项可以让您指定针对何种类型的参数进行参数传递方式的扫描:
在ABAP里理论上采用引用传递的方式进行参数传递,性能上总是优于值传递,具体性能会提高多少,依赖于具体传递的参数类型,无法一概而论。
Security Check – Dynamic and Client-Specific accesses in SELECT - 动态SQL语句的检测
符合下列范式的动态SQL会被扫描出来:
- Dynamic table accesses: SELECT * FROM (dbtab) WHERE …
- Dynamic WHERE conditions: SELECT * FROM dbtab WHERE (where_cond)
- Accesses to certain tables: SELECT * FROM dbtab WHERE …
- Client-specific accesses: SELECT * FROM dbtab FROM WA … CLIENT SPECIFIED …
这个选项并不是禁止您使用动态SQL语句——事实上SAP应用的持久层里有大量的动态SQL语句的使用例子——而是提醒您别忘记了进行SQL注入的预防措施:一旦扫描出来,如果有用户输入参与了这些动态SQL语句的拼接,那就别忘记看看上下文有没有使用CL_ABAP_DYN_PRG对用户输入进行处理。
Search for APPEND and INSERT … INDEX in SORTED Tables
检测所有在有序内表上施加了APPEND操作的地方。有了这个扫描选项,能够帮助您避免下图第13行这种类型的运行时错误。
Check of SY-SUBRC Handing - ABAP关键字调用后系统变量sy-subrc的检测
Jerry至今仍清楚地记得,十多年前上研究生课程《UNIX环境高级编程》时,老师不断地强调在进行系统调用之后一定要检查返回值并进行相应的错误处理。在Jerry看来,错误检测和处理是每一位编程人员都应该具备的基本素养。
对应到ABAP里,就意味着每次调用ABAP的关键字完成某项操作后,都必须检查sy-subrc的值来确认这次操作是否成功。
当然也可以根据项目的实际情况,告诉Code Inspector只检查某些类型的ABAP关键字调用。比如上图意思就是只检查READ TABLE关键字调用后是否进行了sy-subrc的检查。
Missing table content check before calling SELECT … FOR ALL ENTRIES IN
在使用FOR ALL ENTRIES IN 之前,必须先检查内表itab是否为空。这个选项能扫描出没有按照这个规范来编写的代码。