调用ABAP类方法后返回值RV_BOOKS为空的问题排查
问题描述
我编写了全局类ZCL_CHE_UT_BOOK用于单元测试。调用GET_BOOKS方法时,返回值RV_BOOKS能正常获取数据,但调用其他方法后RV_BOOKS变为空,无任何输出。以下是我的代码:
class ZCL_CHE_UT_BOOK definition public final create public . public section. types: BEGIN OF TY_BOOK, CLIENT TYPE ZCHE_BOOKS-CLIENT, BOOKID TYPE ZCHE_BOOKS-BOOKID, LIBRARYID TYPE ZCHE_BOOKS-LIBRARYID, BOOKTITLE TYPE ZCHE_BOOKS-BOOKTITLE, AUTHOR TYPE ZCHE_BOOKS-AUTHOR, GENRE TYPE ZCHE_BOOKS-GENRE, QUANTITY TYPE ZCHE_BOOKS-QUANTITY, CUKY_FIELD TYPE ZCHE_BOOKS-CUKY_FIELD, PRICE TYPE ZCHE_BOOKS-PRICE, P_DATA TYPE ZCHE_BOOKS-P_DATA, END OF TY_BOOK . types: TT_BOOK TYPE STANDARD TABLE OF TY_BOOK WITH DEFAULT KEY . data: LT_BOOKS TYPE TABLE OF ZCHE_BOOKS . methods GET_BOOKS returning value(RV_BOOKS) type TT_BOOK . methods OUTPUT_BOOKS importing !RV_BOOKS type TT_BOOK . methods FIND_RARE_BOOKS importing !RV_BOOKS type TT_BOOK returning value(RV_RARE_BOOKS) type TT_BOOK . methods GET_BOOKS_BY_GENRE importing !RV_BOOKS type TT_BOOK !IV_GENRE type ZCHE_BOOKS-GENRE returning value(RV_TOTAL) type INT4 . PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS ZCL_CHE_UT_BOOK IMPLEMENTATION. METHOD FIND_RARE_BOOKS. DATA: LT_RARE_BOOKS TYPE TABLE OF ZCHE_BOOKS, " For storing special books LS_RARE_BOOK TYPE ZCHE_BOOKS. " Work work with special books LOOP AT RV_BOOKS INTO DATA(LS_BOOK). IF LS_BOOK-QUANTITY < 5 AND LS_BOOK-PRICE > 20. " Additional activity with some books LS_RARE_BOOK = LS_BOOK. APPEND LS_RARE_BOOK TO LT_RARE_BOOKS. ENDIF. ENDLOOP. RV_RARE_BOOKS = LT_RARE_BOOKS. IF RV_RARE_BOOKS IS NOT INITIAL. WRITE: / 'List of rare books:'. LOOP AT RV_RARE_BOOKS INTO LS_RARE_BOOK. WRITE: / 'Book:', LS_RARE_BOOK-BOOKTITLE, 'Author:', LS_RARE_BOOK-AUTHOR, 'Genre:', LS_RARE_BOOK-GENRE. ENDLOOP. ELSE. WRITE: / 'Rare books not found.'. ENDIF. ENDMETHOD. METHOD GET_BOOKS. SELECT * FROM ZCHE_BOOKS INTO TABLE @RV_BOOKS. SORT RV_BOOKS ASCENDING. ENDMETHOD. METHOD GET_BOOKS_BY_GENRE. DATA(LV_TOTAL) = REDUCE INT4( INIT COUNT = 0 FOR C IN RV_BOOKS WHERE ( QUANTITY > 0 AND GENRE = IV_GENRE ) NEXT COUNT = COUNT + C-QUANTITY ). RV_TOTAL = LV_TOTAL. ENDMETHOD. METHOD OUTPUT_BOOKS. WRITE: / 'List of all books:'. LOOP AT RV_BOOKS INTO DATA(LS_BOOK). " Output data by parameters into console WRITE: / 'Book:', LS_BOOK-BOOKTITLE, 'Author:', LS_BOOK-AUTHOR, 'Genre:', LS_BOOK-GENRE. ENDLOOP. ENDMETHOD. ENDCLASS.
问题原因
核心问题是表类型不匹配导致的隐式转换失败:
- 类中定义的
TT_BOOK是基于自定义结构TY_BOOK的内表类型,但在FIND_RARE_BOOKS方法里,LT_RARE_BOOKS和LS_RARE_BOOK用的是数据库表ZCHE_BOOKS的类型。当执行RV_RARE_BOOKS = LT_RARE_BOOKS时,两种不同结构的内表直接赋值会触发隐式转换,ABAP中这种跨类型赋值会导致目标表被初始化为空,最终出现无输出的情况。 - 虽然
GET_BOOKS方法中把数据库表数据查入RV_BOOKS(TT_BOOK类型)时能正常工作,但后续方法中混用不同类型的内表,会破坏数据一致性,引发空表问题。
修复方案
方案1:统一内表类型
把所有操作内表的变量都改成自定义的TT_BOOK和TY_BOOK类型,彻底消除类型不匹配:
METHOD FIND_RARE_BOOKS. DATA: LT_RARE_BOOKS TYPE TT_BOOK, " 替换为TT_BOOK类型 LS_RARE_BOOK TYPE TY_BOOK. " 替换为TY_BOOK类型 LOOP AT RV_BOOKS INTO DATA(LS_BOOK). IF LS_BOOK-QUANTITY < 5 AND LS_BOOK-PRICE > 20. LS_RARE_BOOK = LS_BOOK. APPEND LS_RARE_BOOK TO LT_RARE_BOOKS. ENDIF. ENDLOOP. RV_RARE_BOOKS = LT_RARE_BOOKS. IF RV_RARE_BOOKS IS NOT INITIAL. WRITE: / '稀有书籍列表:'. LOOP AT RV_RARE_BOOKS INTO LS_RARE_BOOK. WRITE: / '书籍:', LS_RARE_BOOK-BOOKTITLE, '作者:', LS_RARE_BOOK-AUTHOR, '分类:', LS_RARE_BOOK-GENRE. ENDLOOP. ELSE. WRITE: / '未找到稀有书籍.'. ENDIF. ENDMETHOD.
方案2:复用数据库表类型(可选)
如果自定义结构TY_BOOK和数据库表ZCHE_BOOKS的结构完全一致,可以直接复用数据库表的类型,省去重复定义:
types: TT_BOOK TYPE STANDARD TABLE OF ZCHE_BOOKS WITH DEFAULT KEY .
这样后续所有内表都使用TT_BOOK和ZCHE_BOOKS类型,从根源避免类型不匹配问题。
额外优化建议
- 尽量不要在类方法里直接用
WRITE输出,单元测试类应专注于数据处理,输出逻辑可以放到调用该类的测试程序中。 - 在
GET_BOOKS方法中添加空表判断,避免后续方法处理空数据时出现异常。
内容的提问来源于stack exchange,提问作者Alexander Chebotarev
相关产品推荐
相关产品推荐

