BCCL Documentation
Index

Delete Operations

BCCL provides two tasks for deleting records from Business Central tables: DELETEDATA for removing specific records identified by primary key, and DELETEALL for bulk-deleting all records that match a view filter. Both operations permanently remove data, so you should use them with care.

Choosing the Right Delete Task

Task Use When Input Required
DELETEDATA You have a list of specific records to delete Input file with primary key values
DELETEALL You want to remove all records matching a filter View filter parameter

If you know exactly which records to remove (for example, from a CSV list of customer numbers), use DELETEDATA. If you want to clear out a range of records based on a filter condition, use DELETEALL.


DELETEDATA -- Delete Specific Records

The DELETEDATA task deletes individual records by looking up their primary key values from an input file. For each row in the input file, BCCL finds the corresponding record in Business Central and deletes it.

How It Works

  1. BCCL reads the input file and the mapping file.
  2. For each record in the input file, it extracts the primary key field values using the mapping.
  3. It looks up the record in the target table by primary key.
  4. If the record is found, it is deleted.
  5. BCCL returns the total count of deleted records.

Only the primary key fields from the input file are used for the lookup. Any additional fields in the input file are ignored during the find operation.

Required Parameters

Parameter Description
-t deletedata Specifies the DELETEDATA task
-s table=N The Business Central table number
-i filename Path to the input file with primary key values
-m mapping.json Path to the mapping file (optional -- if omitted, all fields are auto-mapped)

Input File Formats

DELETEDATA supports all input formats that BCCL handles:

Format Notes
CSV Each row provides primary key values for one record
JSON Array of objects, each containing primary key fields
XML XML document with record elements containing primary key fields
Excel Spreadsheet with primary key values (use -x and -y parameters)

The input file only needs to contain the primary key fields. You do not need to include every field in the table.

Example: Deleting Customers by Number

Step 1: Create the Input File

Create a CSV file named delete-list.csv containing the customer numbers to delete:

custno
"90001"
"90002"
"90003"
"90004"
"90005"

Step 2: Create the Mapping File

Create a mapping file delete-map.json that maps the CSV column to the primary key field (field 1, No., in the Customer table):

[
  {
    "FieldNo": 1,
    "FieldName": "No.",
    "MappedName": "custno",
    "Validate": false
  }
]

Step 3: Run the Delete

bccl -t deletedata -s table=18 -i delete-list.csv -m delete-map.json

Step 4: Review the Result

{
  "Table": 18,
  "Deleted": 5
}

The Deleted count tells you how many records were actually removed. If a record in your input file does not exist in the table, it is simply skipped and not counted.

Validation on Delete

You can enable validation during deletion so that Business Central triggers run when each record is deleted. This is important when delete triggers contain business logic such as cascading deletes, posting checks, or audit logging.

To enable validation, use the ValidateOnDelete setting. When validation is enabled, BCCL calls Record.Delete(true) instead of Record.Delete(false).

If a validated delete fails for a particular record (for example, because a trigger raises an error), that record is not deleted and is not included in the Deleted count.

Tables with Compound Primary Keys

For tables with multi-field primary keys, your input file and mapping must include all primary key fields. For example, to delete Sales Lines (table 37), you need both the Document Type, Document No., and Line No. fields:

[
  {
    "FieldNo": 1,
    "FieldName": "Document Type",
    "MappedName": "doctype",
    "Validate": false
  },
  {
    "FieldNo": 3,
    "FieldName": "Document No.",
    "MappedName": "docno",
    "Validate": false
  },
  {
    "FieldNo": 4,
    "FieldName": "Line No.",
    "MappedName": "lineno",
    "Validate": false
  }
]

Auto-Mapping Without a Mapping File

If you omit the -m parameter, BCCL auto-maps all fields in the table. In this case, your input file column names must match the Business Central field names exactly (with spaces replaced by underscores). For delete operations, only the primary key fields actually matter, but all field names must still be resolvable.

Using an explicit mapping file is recommended because it gives you control over exactly which columns are expected.

Integration Events

The DELETEDATA codeunit publishes integration events for AL developers:

Event When It Fires
OnBeforeDeleteData Once, before any records are processed
OnBeforeDelete Before each individual record is deleted
OnAfterDelete After each individual record is deleted
OnAfterDeleteData Once, after all records have been processed

DELETEALL -- Bulk Delete by Filter

The DELETEALL task deletes every record that matches a view filter. Unlike DELETEDATA, it does not require an input file -- the view filter alone determines which records are removed.

How It Works

  1. BCCL opens the target table and applies the view filter.
  2. It counts the matching records.
  3. It calls DeleteAll on the filtered record set.
  4. It returns the count of deleted records.

Required Parameters

Parameter Description
-t deleteall Specifies the DELETEALL task
-s table=N The Business Central table number
-s view=WHERE(...) A view filter selecting which records to delete

The View Filter Is Mandatory

As a safety measure, BCCL requires a view filter for DELETEALL. If you omit the view parameter, BCCL returns an error:

The view parameter is required when using DELETEALL

This prevents accidental deletion of an entire table. You must always provide a filter that limits which records are affected.

Optional: Validation on Delete

You can enable validation by adding the validate setting:

bccl -t deleteall -s table=18 "view=where(No.=filter(90000..99999))" -s validate=true

When validate is set to true or yes, BCCL calls DeleteAll(true), which fires the OnDelete trigger for each record. When omitted or set to false, BCCL calls DeleteAll(false), which is faster but skips trigger logic.

Example: Deleting a Range of Test Customers

bccl -t deleteall -s table=18 "view=where(No.=filter(90000..99999))"

This deletes all customers with numbers from 90000 through 99999. The response confirms the count:

{
  "Table": 18,
  "Deleted": 47
}

Example: Deleting by Multiple Criteria

You can use more complex filters to target records precisely:

bccl -t deleteall -s table=18 "view=where(No.=filter(T*),Blocked=filter(<>0))"

This deletes all customers whose number starts with T and whose Blocked field is not zero.

Example: Deleting with Validation

bccl -t deleteall -s table=50000 "view=where(Status=filter(Obsolete))" -s validate=true

This deletes records with an Obsolete status from a custom table, running the OnDelete trigger for each record.

Integration Events

The DELETEALL codeunit publishes integration events for AL developers:

Event When It Fires
OnBeforeDeleteAll Before the bulk delete operation begins
OnAfterDeleteAll After the bulk delete operation completes

Comparing DELETEDATA and DELETEALL

Feature DELETEDATA DELETEALL
Selection method Input file with primary keys View filter
Input file required Yes No
Mapping file Optional (recommended) Not used
View filter Not used Required
Validation support Via ValidateOnDelete Via -s validate=true
Granularity Per-record (from file) All matching records
Best for Deleting a known list of records Clearing records by range or condition

Safety Guidelines

Delete operations are permanent. Business Central does not provide a built-in undo for record deletions. Follow these practices to protect your data:

Before You Delete

  1. Export the records first. Use the GETDATA task with the same filter to export the records you are about to delete. Save this export as a backup.
   bccl -t getdata -s table=18 "view=where(No.=filter(90000..99999))" -f csv -o backup.csv
  1. Verify your filter. Run a GETDATA with your intended filter and check that it returns only the records you want to delete. A misconfigured filter could match records you did not intend to remove.
  2. Test in a sandbox. When possible, test delete operations in a sandbox or test environment before running them in production.

During Deletion

  1. Use validation when business logic matters. If the table has OnDelete triggers that perform cascading cleanup (such as deleting related records or posting reversal entries), enable validation to ensure that logic runs.
  2. Use verbose mode for troubleshooting. Add -v to your command to see detailed request and response information if something goes wrong.

After Deletion

  1. Check the Deleted count. Compare the returned Deleted count against your expectations. If it is higher or lower than expected, investigate before proceeding.
  2. Keep your backup files. Retain the exported backup until you have confirmed that the deletion was correct and complete.

Tips and Best Practices

  • Use DELETEDATA when you have a specific list of records from an external source (such as a list of obsolete account numbers from a spreadsheet).
  • Use DELETEALL when cleaning up records by range, status, or date -- any condition expressible as a Business Central view filter.
  • For DELETEALL, always double-check your filter by running a GETDATA with the same filter first.
  • When deleting from tables with complex relationships, enable validation to ensure referential integrity is maintained.
  • Remember that the Deleted count for DELETEDATA reflects only records that were found and successfully deleted. Records in your input file that do not exist in the table are silently skipped.