Program RVV50R10C (Deliver Documents Due for Delivery) usually been set up as a background job to generate delivery documents every day. It runs perfectly until one Monday, the user finds fewer delivery orders have been created than before and especially no delivery anymore for STO(stock transfer orders). There's a dump error of 'TAB_DUPLICATE_KEY' for every background job with RVV50R10C like below:
Symptom
When you execute transaction MB5T you receive a program termination of type ITAB_DUPLICATE_KEY in program SAPLME06.
Other Terms
MB5T, \FUNCTION-POOL=ME06\CLASS=LCL_DB}\DATA=MT_DATA, PRIMARY_KEY, ARRAY_READ EKPV
Reason and Prerequisites
This issue is caused by a program error.
Solution
Implement attached program correction.
*--------------------------------------------------------------------*
* Read shipping data by using array operation
*--------------------------------------------------------------------*
METHOD array_read.
* define local types
TYPES:
lty_t_input TYPE SORTED TABLE OF ekpo_key
WITH UNIQUE KEY ebeln ebelp.
* define local data objects
DATA: lx_raise TYPE REF TO lcx_raise,
ls_input TYPE ekpo_key,
lt_input TYPE lty_t_input,
lt_array TYPE STANDARD TABLE OF ekpo_key WITH DEFAULT KEY,
lt_data TYPE me->lif_types~type_t_ekpv.
FIELD-SYMBOLS:
<ls_array> TYPE ekpo_key,
<ls_data> TYPE ekpv.
*
* if there are more than 5,000 entries -> refresh and start fresh
IF lines( me->mt_data ) GE me->mc_max.
* Stelle sicher, dass nur das noetigste von der DB-gelesen wird
me->reset( ).
INSERT LINES OF it_array INTO TABLE lt_input.
SELECT * FROM ekpv
INTO TABLE me->mt_data
FOR ALL ENTRIES IN lt_input "1864606
WHERE ebeln = lt_input-ebeln
AND ebelp = lt_input-ebelp.
IF sy-subrc GT 0 OR lines( me->mt_data ) EQ 0.
RAISE EXCEPTION TYPE lcx_raise.
ENDIF.
et_data = me->mt_data.
* mix up existing with new information
ELSE.
LOOP AT it_array ASSIGNING <ls_array>.
READ TABLE me->mt_data
WITH TABLE KEY ebeln = <ls_array>-ebeln
ebelp = <ls_array>-ebelp
ASSIGNING <ls_data>.
IF sy-subrc EQ 0.
IF et_data IS SUPPLIED.
READ TABLE et_data WITH TABLE KEY ebeln = <ls_array>-ebeln
ebelp = <ls_array>-ebelp
TRANSPORTING NO FIELDS.
CHECK sy-subrc GT 0.
INSERT <ls_data> INTO TABLE et_data.
ENDIF.
ELSE.
READ TABLE lt_input WITH KEY ebeln = <ls_array>-ebeln
TRANSPORTING NO FIELDS.
CHECK sy-subrc GT 0.
ls_input-ebeln = <ls_array>-ebeln.
ls_input-ebelp = <ls_array>-ebelp. "1902763
INSERT ls_input INTO TABLE lt_input.
ENDIF.
ENDLOOP.
* Lese Rest von der DB.
IF lines( lt_input ) GE 1.
SELECT * FROM ekpv
INTO TABLE lt_data
FOR ALL ENTRIES IN lt_input
WHERE ebeln = lt_input-ebeln.
IF sy-subrc EQ 0.
* first interation cycle
IF me->mv_iter IS INITIAL. "1864606
INSERT LINES OF lt_data INTO TABLE me->mt_data.
ELSE.
LOOP AT lt_data ASSIGNING <ls_data>. "1864606
READ TABLE me->mt_data WITH TABLE KEY ebeln = <ls_data>-ebeln
ebelp = <ls_data>-ebelp
TRANSPORTING NO FIELDS.
CHECK sy-subrc GT 0.
INSERT <ls_data> INTO TABLE me->mt_data.
ENDLOOP.
ENDIF.
* do array read only up to 2 interation cycles
IF et_data IS SUPPLIED AND me->mv_iter LE 1. "1864606
TRY.
lt_array = lt_input.
me->mv_iter = me->mv_iter + 1.
me->array_read( EXPORTING it_array = lt_array "1864606
IMPORTING et_data = et_data ).
CATCH lcx_raise INTO lx_raise.
CLEAR et_data.
RAISE EXCEPTION lx_raise.
ENDTRY.
ENDIF.
ELSE.
RAISE EXCEPTION TYPE lcx_raise.
ENDIF.
ENDIF.
ENDIF.
ENDMETHOD. "array_read
* first interation cycle
IF me->mv_iter IS INITIAL. "1864606
INSERT LINES OF lt_data INTO TABLE me->mt_data. "<<<<<<======DUMP LINE
ELSE.
LOOP AT lt_data ASSIGNING <ls_data>. "1864606
READ TABLE me->mt_data WITH TABLE KEY ebeln = <ls_data>-ebeln
ebelp = <ls_data>-ebelp
TRANSPORTING NO FIELDS.
CHECK sy-subrc GT 0.
INSERT <ls_data> INTO TABLE me->mt_data.
ENDLOOP.
ENDIF.
METHOD reset.
CLEAR: me->mt_data, me->mv_iter. "1864606
ENDMETHOD. "reset
me->reset( ).
INSERT LINES OF it_array INTO TABLE lt_input.
SELECT * FROM ekpv
INTO TABLE me->mt_data
FOR ALL ENTRIES IN lt_input "1864606
WHERE ebeln = lt_input-ebeln
AND ebelp = lt_input-ebelp.
At this moment inside the big loop perdue delivery, this method 'array_read' has been called for the first STO delivery with a specific item number as it_array. Below is a good place to set a breakpoint to understand the big loop.
Table me->mt_data contains less than 5000 now, for this specific STO item from it_array (loop of due delivery), if it's not existed in me->mt_data which get from 2nd round call with shrunk item numbers.
* Lese Rest von der DB.
IF lines( lt_input ) GE 1.
SELECT * FROM ekpv
INTO TABLE lt_data
FOR ALL ENTRIES IN lt_input
WHERE ebeln = lt_input-ebeln.
IF sy-subrc EQ 0.
* first interation cycle
IF me->mv_iter IS INITIAL. "1864606
INSERT LINES OF lt_data INTO TABLE me->mt_data.
Then comes the real issue now: lt_input contains only 1 STO with 1 item number, and it did not exist at me->mt_data. Now fetching from EKPV happens again without considering the specific item number! It leads to duplicated keys for sure when insert to TABLE me->mt_data. Cause delivery due is for this specific STO specific item, but the previous mt-data fetched only for the first item of all Due delivery related STO. Unless this is the only item number of this STO due for delivery, otherwise dump will list the first STO with the item number which is duplicated.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
5 | |
4 | |
3 | |
3 | |
2 | |
2 | |
2 | |
2 | |
2 | |
2 |