Удалить текущую строку из внутренней таблицы в цикле

Можно ли безопасно удалить активную строку при циклическом перемещении по внутренней таблице?

В качестве примера рассмотрим этот код:

LOOP AT lt_itab INTO ls_wa.
    IF [...] . " A check that can't be done inside a 'DELETE lt_itab WHERE'
        DELETE lt_itab INDEX sy-tabix
        " OR
        DELETE lt_itab FROM ls_wa.
    ENDIF.
ENDLOOP.

Безопасно ли удалять записи, подобные этому, или эта логика не будет вести себя так, как предполагалось?

Должен ли я вместо этого хранить уникальный идентификатор строк во временном itab и запускать a DELETE lt_itab WHERE после цикла?

Я предполагаю, что операции удаления в записях, отличных от того, который загружен в текущей итерации, определенно вызовут проблемы, но я не уверен, что это допустимая, не говоря уже о хорошей практике.

Ответы

Ответ 1

Безопасно или нет, во многом зависит от ваших навыков кодирования. Он имеет определенный результат, и вам нужно правильно использовать команды. Обычно это безопасно, если после оператора DELETE в цикле ничего не происходит. Вы можете выпустить инструкцию CONTINUE сразу после удаления, чтобы убедиться, что это так.

Не используйте DELETE lt_itab INDEX sy-tabix. Если вы используете какой-либо оператор в своей проверке, который меняет sy-tabix как побочный эффект (например, просматривая какую-либо запись в контрольной таблице - или вызывающий функциональный модуль/метод, который делает это), вы в конечном итоге удалите неправильные строки.

Имейте в виду, что вы можете просто использовать оператор DELETE lt_itab. в своем примере, поскольку строка для удаления является текущей.

Если ваша таблица может иметь несколько идентичных строк, ваш второй вариант DELETE lt_itab FROM ls_wa. удалит все из них, а не только текущую, зависит от ваших требований.


EDIT: повторить "определенный результат": текущая строка удаляется. Нет "продолжения со следующей строкой" - с добавлением INTO var вы на самом деле скопировали всю строку в свою переменную. Эта переменная не будет затронута, она просто не синхронизирована с таблицей. Это может быть преднамеренным - система не знает этого. Если вместо этого вы используете символ поля, это будет UNASSIGNED, что - опять-таки - может быть то, что вы намеревались, а затем, возможно, нет.