0

delete_recordset in X++, often written simply as delete_from, is a set-based operation that removes multiple records in just one go. Just as insert_recordset is preferred for bulk inserts, delete_from is the recommended way to delete multiple records efficiently because it generates a single SQL DELETE statement and runs it in one database round trip.

To delete records in bulk, you wrap your operation in a transaction for consistency:

ttsBegin;

// Delete all old transactions for a specific account
delete_from CustTransHistory
    where CustTransHistory.AccountNum == 'C1000';

ttsCommit;

Here the delete_from keyword begins the operation, the table buffer indicates the target, and the where clause specifies which rows to remove. This Delete_From to Delete Multiple Records is faster than looping through each record individually, especially when dealing with thousands of rows.

Another example:

ttsBegin;

// Delete a record by RecId
delete_from myTable
    where myTable.RecId == 44556677;

ttsCommit;

This snippet shows a direct approach where a specific record is deleted. The phrase delete_from myTable where mytable. Recid = 12345677 is commonly seen in demos, though you would replace the RecId with the one relevant to your scenario.

There are times when you need row-level control. In such cases, you can use a while select forUpdate loop and call the delete() method on each row:

ttsBegin;

SalesLine line;
while select forUpdate line
    where line.SalesId == 'SO-2025'
{
    // Custom logic could go here
    line.delete();
}

ttsCommit;

This approach is slower for large sets, but useful when you need to run validateDelete, doDelete, or perform other updates. For example, if someone asks, How do I Delete a Product/Item programatically in X++, you would usually demonstrate a looped approach so the system logic attached to that table is respected.

From a business use-case perspective, imagine this requirement: the objective of my x++ query is bulk delete all sales orders that are open (backorder) and don’t have a salesline. In that scenario, you would likely build a Query object that joins SalesTable and SalesLine, adds the conditions for backorder status and missing lines, and then use it as the driver for a delete_from statement. This combines the power of declarative querying with set-based deletion.

And yes if you are thinking via X++ I can delete the records using this entity when working through data entities, the truth is that under the hood, the efficiency still comes from delete_from for bulk work.

So what this means for you: delete_from is the high-performance way to wipe out sets of records in one shot, while looping with delete() is the safer route when you need to enforce table logic or validations. Both patterns are essential in D365FO, depending on whether speed or business rules are the priority.

Have a Question ?

Fill out this short form, one of our Experts will contact you soon.

Talk to an Expert Today

Call Now

Call Now800-453-5961