前言
_以下场景发生背景为:单据都是通过自定义程序,调用BAPI去创建。_
场景描述:
有些系统上线前期,可能会有退货的销售订单(或采购订单)先进入系统,交货单过账后,如果物料原来在mard中没有记录的话,系统会自动扩充mard表,然后紧接着再创建正向的销售订单(或采购订单),仍然会报
V1 39(物料 &1 不存在于存储地点 &2 &3) 错误,即mard表中物料未扩充存储地点。
问题原因
在执行退货的订单及交货时,会先查询mard记录,并将结果集缓存到buffer中,过账后,虽然会自动扩充mard,但是buffer没有更新,所以再做正向的订单及交货时,仍然会先查buffer,所以报物料未扩充存储地点的错误
解决办法
在做正向的订单前,调用FM " MARD_CLEAR_UPDATE_BUFFER "清除mard缓存,代码如下:
CALL FUNCTION 'MARD_CLEAR_UPDATE_BUFFER' EXPORTING iv_clear_all_flag = abap_true.MARD_CLEAR_UPDATE_BUFFER 的源代码如下:
FUNCTION mard_clear_update_buffer.*"----------------------------------------------------------------------*"*"Local Interface:*" IMPORTING*" REFERENCE(IT_MATNR) TYPE CMD_BS_MAT_T_MAT_ID OPTIONAL*" REFERENCE(IV_CLEAR_ALL_FLAG) TYPE BOOLEAN DEFAULT SPACE*"----------------------------------------------------------------------DATA : lv_matnr TYPE matnr.
IF iv_clear_all_flag EQ abap_true. REFRESH imard. CLEAR imard. REFRESH tmard. CLEAR tmard. REFRESH omard. CLEAR omard. REFRESH nmard. CLEAR nmard. REFRESH mard_matnr. CLEAR mard_matnr. REFRESH mard_keytab. CLEAR mard_keytab. REFRESH matnr_plant_gen. CLEAR matnr_plant_gen. REFRESH imardh. CLEAR imardh. REFRESH:gt_mard_agg,gt_mard_agg_failed. CLEAR kz_buf_not_empty. EXIT. ENDIF.
LOOP AT it_matnr INTO lv_matnr. DELETE tmard WHERE matnr = lv_matnr. DELETE imard WHERE matnr = lv_matnr. DELETE omard WHERE matnr = lv_matnr. DELETE nmard WHERE matnr = lv_matnr. DELETE mard_matnr WHERE matnr = lv_matnr. DELETE mard_keytab WHERE matnr = lv_matnr. DELETE matnr_plant_gen WHERE matnr = lv_matnr. DELETE imardh WHERE matnr = lv_matnr. DELETE gt_mard_agg WHERE matnr = lv_matnr. DELETE gt_mard_agg_failed WHERE matnr = lv_matnr. ENDLOOP.ENDFUNCTION.总结
缓存机制对于数据库来说,是减轻了不少的额外开销,好处自然不必说,有时候却又能把人折腾的不轻,而且问题一般也很难追踪和发现,所以碰到了,记录下来,避免再次掉坑。