Guidelines for Partners
Introduction
In Microsoft Dynamics 365 Business Central, each table uses a primary key – a defined set of one or more fields – to uniquely identify its records, speed up lookups, and enforce data integrity. Once a table is published, its primary key maps directly to a clustered index in the SQL Server schema and cannot be changed by extensions. However, Business Central provides two supported mechanisms to work with key values at runtime without altering the SQL definition:
- Rename(): Available on standard tables whose primary key consists of a single field. This method updates the key value in place (and cascades the change to related tables), bypassing the usual constraints that would prevent modifying a primary key.
- Logical keys in buffer tables: temporary tables – used during processes like posting or batch calculations—never persist to SQL and some of them rely on an in‑memory “logical key” (commonly called GroupID) to decide whether to merge a new record with an existing one or insert a separate line. Through published events, you can override the default GroupID to apply wanted grouping to your business needs.
This article dives into how physical primary keys and secondary keys differ from these in‑memory logical keys, why buffer tables exist, how Rename() works under the hood, and how to use buffer‑table events (with Invoice Posting Buffer as our running example) to redefine record uniqueness on the fly.
Standard Tables vs. Temporary Tables
In Business Central, standard tables (TableType = Normal) persist their data and definitions in SQL Server. Their primary key—as declared first in the keys section in AL—becomes a clustered index in the database, enforcing uniqueness and referential integrity on every Insert, Modify, or Delete. Changing that key’s structure requires rebuilding the table (with potential data-migration risks) and is therefore not supported by extensions.
By contrast, temporary tables (TableType = Temporary) live only in server memory during a single session or process—for example, while posting a journal or running a batch calculation—and are never written back to SQL. Since SQL Server does not apply constraints or indexes to these in‑memory tables, Business Central maintains its own “logical key” mechanism: it concatenates selected fields into a some sort of GroupID string and, on each Update, compares it against existing buffer rows. If a matching GroupID exists, the new values are merged (e.g., summed); otherwise, a new row is inserted.
Temporary tables’ in‑memory nature delivers high performance and, in some cases they give developers the flexibility to override GroupID logic through published events, where it is possible to control exactly how and when records combine.
The Role of Primary Keys
A primary key in AL is a set of one or more fields declared in the keys section:
This definition directs SQL Server to create a clustered index on Name and ensure each value is unique. If we were to add some data, for example:
The insert of 3rd row will throw an error:
Business Central uses the primary key for record operations like:
- Get: Load a specific record by key value.
- Insert: Block insertion of a duplicate key(data).
- Modify: Update non‑key fields while preserving the key.
- Delete: Remove a record by key.
- Rename: Change the key value (see below).
Without a primary key, the system cannot reliably locate, sort, or maintain the integrity of records.
Secondary Keys and Unique Keys
Secondary keys (non‑clustered indexes) follow the primary key in your table definition. They speed lookups on other field combinations:
Here, SK creates an index on Surname. A table can have multiple secondary keys, each optimizing different query patterns. Secondary keys affect read performance positively but can slow writes due to additional index maintenance.
Changing Key Values with Rename
When a standard table’s primary key is a single field, you can change its value at runtime using Rename(). Using existing data to showcase how this works:
The first Message()shows the row that is inserted:
The second Message()shows the same row but now renamed:
Rename updates the record’s key and cascades changes to all related tables, preserving referential integrity. It bypasses the OnModify() trigger to avoid infinite loops and the simple := would not work, because Modify() procedure throws error for primary keys. For tables with composite keys, Rename is unsupported; then it is needed to manually insert a new record with the desired key values, copy data, and delete the original.
Logical Keys in Temporary Buffer Tables
Temporary buffer tables sometimes do not rely on their declared primary key for uniqueness during processing. Instead, Business Central computes a GroupID string at runtime by concatenating critical fields. When a new record arrives, the buffer checks if a row with that GroupID exists. If found, the buffer updates the existing row (for example, summing amounts). If not, it inserts a new row.
This runtime behavior simulates a primary key in memory, allowing records to merge or remain distinct according to business rules. Crucially, this logic can be extended via events published by Microsoft in certain buffer tables.
There are 166 temporary tables in BC26, W1 version. But only 2 of them have available events or extendable internal methods named OnBuildPrimaryKey…:
- Table 55 “Invoice Posting Buffer”
- Table 595 “Exch. Rate Adjmt. Buffer”
Each uses a computed GroupID to merge or insert buffer rows and can be modified by subscribing the event that is inside the grouping procedure.
Example for Overriding Buffers’ Grouping
In this example we populate a temporary Invoice Posting Buffer with three parameter records but never use a raw Insert; instead we call InvBuf.Update(ParamBuf) each time. Because the first two records share the exact same key fields (Journal Template, Line Type, G/L Account, both Global Dimensions and Job No. = JOB100) and we fill both LCY and FCY amounts, the buffer’s in‑memory logic computes an identical GroupID and automatically merges them—summing Amount (100 + 1000 → 1100) and VAT (10 + 100 → 110)—into a single row. The third record, having a different Job No. (JOB200), generates a new GroupID and is inserted as its own line by calling Insert() method in Update() procedure, since GroupID is not yet recognized. This pattern shows how you can define precisely which fields drive your grouping criteria and let Business Central aggregate or separate posting lines on the fly, all without altering the physical SQL schema.
When and Why to Use These Techniques: Best practices
Use Rename when it is needed to correct a single‑field key in a standard table (e.g., customer, vendor, item). It preserves all related data automatically. And understand procedure’s cascading impact.
Use event‑driven GroupID overrides in buffer tables when business requirements demand finer or different grouping logic during posting or processing. Common scenarios include:
- Separating posting lines by a newly introduced field (e.g., department, project phase).
- Preventing unwanted aggregation in VAT or analysis reports.
- Customizing journal posting behavior without altering core code.
These approaches keep your solution upgrade‑safe, maintainable, and aligned with platform best practices, since you never modify base table definitions. Append only essential fields to GroupID to avoid excessive fragmentation.
Never attempt to redefine declared keys via table extensions; it is not possible to change or modify primary key, only manipulate it in some circumstances.
Conclusion
Manipulating primary key behavior in Business Central is possible and safe when you stay within supported methods. The Rename method handles single‑field key value changes in standard tables, while event‑driven logic in some temporary buffer tables allows you to redefine logical uniqueness at runtime. By mastering these techniques, you can deliver flexible, maintainable, and upgrade‑proof solutions that meet real business demands without compromising the core system.