bcquality/community/knowledge/performance/deleteall-skips-ondelete-unless-runtrigger.md
Jeremy Vyska f5156c61de Add 15 community knowledge articles from BC Code Intel ingest
Ingests net-new /community knowledge from BC Code Intelligence, surviving
the admission test, gray-zone salvage, and dedup against the full corpus.

Domains: ui (6), error-handling (3), performance (2), upgrade (1),
appsource (1), security (1), telemetry (1). The two BC24 No. Series
migration drafts are merged into one article.

Adds good/bad AL samples for the clean-fit articles (error-handling,
performance, security, telemetry). UI and appsource remain knowledge-only.

Validator and knowledge-index checks pass (207 articles).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:02:48 +02:00

1.7 KiB

bc-version domain keywords technologies countries application-area
all
performance
deleteall
ondelete
run-trigger
set-based-delete
bulk-delete
triggers
validation
al
w1
all

DeleteAll skips OnDelete unless you pass RunTrigger

Contributions welcome — open a PR to refine or extend this article.

Description

Record.DeleteAll() — equivalently DeleteAll(false) — translates to a single set-based SQL DELETE and does not run AL OnDelete triggers or field/table validations. Only database-level referential constraints still apply. To run OnDelete logic you must call DeleteAll(true), which then deletes record-by-record and forfeits the set-based performance, making it equivalent to a FindSet loop calling Delete(true). The common misconception, which training data reproduces, is that DeleteAll iterates and fires OnDelete per record; it does not. (Parameterless Delete() likewise defaults to Delete(false) and skips OnDelete.)

Best Practice

Use DeleteAll() / DeleteAll(false) for bulk deletion only when no AL OnDelete cleanup is required — it is the fast, set-based form. When OnDelete logic must run (cascading deletes, ledger cleanup, integration events), pass DeleteAll(true) and accept the row-by-row cost, or refactor the cleanup to run explicitly before the bulk delete.

Anti Pattern

Calling DeleteAll() and assuming dependent records, integration events, or validation side effects are handled by OnDelete. The deletion succeeds but the AL-side cleanup never runs, leaving orphaned data — and adding a manual FindSet/Delete loop "for safety" reintroduces the per-record cost the set-based form was chosen to avoid.