Single-field primary key requires the NotBlank property

Properties
AC0002 Warning Design Code Fix Ignore Obsolete

When a table defines a single primary key field of type Code or Text, the platform does not prevent inserting a record with a blank key value unless the field explicitly sets NotBlank = true.

The danger surfaces when that blank-key record is deleted or renamed. The platform looks for fields in other t ables that have a TableRelation pointing to this table — and every one of those fields that currently holds no value matches the blank primary key. The platform then cascades the delete or rename to all of those relate d records, silently destroying data that was never associated with the blank key in the first place.

Set NotBlank = true on the primary key field to prevent blank-key records from being created.

Example

The following table has a single Code field as primary key without the NotBlank property.

Consider the example where a user accidentally creates an new Item Category with a blank code. If they then rename it to 'ABC', the platform cascades the rename and every Item with a blank Item Category Code will now stamped with 'ABC'.

table 50100 "Item Category"
{
    fields
    {
        field(1; "Code"; Code[20]) // Single-field primary key requires the NotBlank property [AC0002]
        {
        }
    }

    keys
    {
        key(PK; "Code")
        {
            Clustered = true;
        }
    }
}

To fix this, set NotBlank = true to prevent blank-key records from being created in the first place.

table 50100 "Item Category"
{
    fields
    {
        field(1; "Code"; Code[20])
        {
            NotBlank = true;
        }
    }

    keys
    {
        key(PK; "Code")
        {
            Clustered = true;
        }
    }
}

Exception

Setup tables are not reported. A setup table holds a single record, and its primary key is always blank by design. No other table relates to that record, so there is nothing for a rename or delete to cascade to.

The rule recognises a setup table by convention, not by checking inbound table relations. A table counts as a setup table when either of these is true:

  • its only primary key field is a Code field named Primary Key or PrimaryKey;
  • it declares a parameterless GetRecordOnce procedure without a return value.
table 50100 "My Setup"
{
    fields
    {
        field(1; "Primary Key"; Code[10]) // Not reported: setup table
        {
        }
        field(2; "Default Location Code"; Code[10])
        {
        }
    }

    keys
    {
        key(PK; "Primary Key")
        {
            Clustered = true;
        }
    }
}

A single-record table that does not follow this convention is still reported. A Text Primary Key field is one example. A key field named PK or Code without a GetRecordOnce procedure is another. Set NotBlank = false explicitly on such a field to record that the blank key is intended.

See also