使用BAPI_OBJCL_DELETE删除设备类异常:调试有效正常模式无效
设备类删除问题分析(调试成功但正常运行失败)
问题描述
我尝试用BAPI_OBJCL_DELETE删除设备类,调试模式下能成功删除,但正常运行时却无法删除。我用了以下程序执行删除操作,也试过COMMIT WORK和BAPI_TRANSACTION_COMMIT,麻烦分析问题原因。
原程序代码
Get list of current class assignments. CALL FUNCTION 'CLAF_CLASSIFICATION_OF_OBJECTS' EXPORTING classtype = cv_klart object = iv_objnum objecttable = cv_object_tab TABLES t_class = lt_class t_objectdata = lt_obj EXCEPTIONS no_classification = 1 no_classtypes = 2 invalid_class_type = 3 OTHERS = 4 IF sy-subrc EQ 0 AND lt_class IS NOT INITIAL. lv_objectkey = iv_objnum. "Delete all existing classes. LOOP AT lt_class INTO ls_class. CALL FUNCTION 'BAPI_OBJCL_DELETE' EXPORTING * OBJECTKEY = objecttable = classnum = classtype = * CHANGENUMBER = * KEYDATE = SY-DATUM * OBJECTKEY_LONG = TABLES return = . CALL FUNCTION 'BAPI_OBJCL_DELETE' EXPORTING objectkey = lv_objectkey objecttable = cv_object_tab classnum = ls_class-class classtype = cv_klart TABLES return = lt_return. IF sy-subrc NE 0. APPEND LINES OF lt_return TO et_messages. ENDIF. WAIT UP TO 1 SECONDS. COMMIT WORK. ENDIF. WAIT UP TO 1 SECONDS. ENDLOOP. WAIT UP TO 1 SECONDS. ENDIF.
问题原因分析
- 无效BAPI调用干扰逻辑:循环里连续调用两次
BAPI_OBJCL_DELETE,第一次调用时所有必填参数为空,会触发BAPI错误,干扰后续正常调用的事务状态。调试时单步执行可能忽略这个错误影响,但正常运行时会直接打乱流程。 - 事务提交时机错误:每次调用BAPI后就执行
COMMIT WORK,频繁提交会导致事务上下文混乱,甚至引发锁冲突。BAPI设计更适合批量操作后统一提交,多次提交在快速执行的正常模式下,很容易因锁资源未释放就提交,导致后续删除操作失败。 - 语法结构错误:代码里的
ENDIF位置完全错误,LOOP循环内的IF sy-subrc NE 0.对应的ENDIF放在了ENDLOOP前面,导致循环结构混乱,正常运行时可能提前退出循环,根本没执行完所有删除操作。调试时单步执行没暴露这个问题,但批量执行时逻辑直接出错。 - 返回值处理不全:只在
sy-subrc非0时收集返回信息,但很多BAPI即使sy-subrc为0,return表里也会有警告或错误提示,这些信息是正常运行时定位问题的关键,但代码里没收集,导致无法排查。 - 无效等待语句:添加的
WAIT UP TO 1 SECONDS完全没用,调试时暂停过程让锁释放了,但正常运行时这个等待既解决不了根本问题,还拖慢程序。
修正方案
- 移除第一个无参数的
BAPI_OBJCL_DELETE调用,只保留参数正确的那一次。 - 把事务提交移到循环结束后,用
BAPI_TRANSACTION_COMMIT并设置wait = 'X',确保提交完成后再结束。 - 修正循环的语法错误,确保
LOOP和ENDLOOP、IF和ENDIF配对正确。 - 每次调用BAPI后不管
sy-subrc如何,都收集return表的信息,方便排查问题。 - 删除所有无用的
WAIT UP TO语句。
修正后示例代码
* 获取当前类分配列表 CALL FUNCTION 'CLAF_CLASSIFICATION_OF_OBJECTS' EXPORTING classtype = cv_klart object = iv_objnum objecttable = cv_object_tab TABLES t_class = lt_class t_objectdata = lt_obj EXCEPTIONS no_classification = 1 no_classtypes = 2 invalid_class_type = 3 OTHERS = 4. IF sy-subrc EQ 0 AND lt_class IS NOT INITIAL. lv_objectkey = iv_objnum. " 删除所有已存在的类 LOOP AT lt_class INTO ls_class. CLEAR lt_return. CALL FUNCTION 'BAPI_OBJCL_DELETE' EXPORTING objectkey = lv_objectkey objecttable = cv_object_tab classnum = ls_class-class classtype = cv_klart TABLES return = lt_return. " 收集所有返回信息,不管调用是否返回sy-subrc错误 APPEND LINES OF lt_return TO et_messages. ENDLOOP. " 统一提交所有删除操作,等待提交完成 CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'. ENDIF.
内容的提问来源于stack exchange,提问作者Anjali Sinha
相关产品推荐
相关产品推荐

