bcquality/microsoft/knowledge/performance/avoid-cloning-records-before-modify-delete-in-loops.md
Jesper Schulz-Wedde bad62d2763 Add per-row performance guidance
Document SetAutoCalcFields for per-row FlowFields and direct writes on iterated records, with focused reviewer retrieval cues.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 85be3fc4-5253-47b8-ba1b-6b8fd188fcea
2026-07-14 11:41:47 +02:00

1.7 KiB

bc-version domain keywords technologies countries application-area
all
performance
clone
copy
recordref
gettable
by-value
modify
delete
loop
al
w1
all

Avoid cloning records before Modify or Delete in loops

Description

Microsoft's AL database-method performance guidance states that cloning an iterated record before Modify or Delete restarts the SQL SELECT and issues an extra SQL statement for every row. The runtime treats Record.Copy, RecordRef.GetTable, and passing a record by value to a writing helper as clones in this situation.

Best Practice

Use FindSet(true) when the loop writes the traversed rows, and call Modify or Delete on that iterating record variable. If generic code is required, open and iterate the RecordRef directly instead of calling GetTable for each typed record. Keep a per-row loop when validation or row-specific behavior is required; this rule does not imply that ModifyAll or DeleteAll is equivalent.

See sample: avoid-cloning-records-before-modify-delete-in-loops.good.al.

Anti Pattern

Inside an active traversal, copy the current row, convert it with RecordRef.GetTable, or pass it without var to a helper, then call Modify or Delete on that clone. Do not flag read-only snapshots, temporary records, or copies used to write a different target table; the documented extra-statement concern is clone-before-write on the traversed table.

See sample: avoid-cloning-records-before-modify-delete-in-loops.bad.al.