rules repository

A-3110 Always define a primary key item for forms with a DML process.

Severity Error SQL-based Test Free New

Reason

The Form - Automatic Row Processing (DML) process identifies the row to update or delete through the form's primary key items. If no item of the form region is marked as Primary Key, the process has no key to locate the row, so updates and deletes cannot work.

Mark the item that holds the key (for example P10_CUSTOMER_ID) as Primary Key in its Source settings. Use the ROWID column as primary key item if the table has no primary key.

Example

Non-Compliant Example

page 10 (
    // ...
    region customer (
        name: Customer
        type: form
        // ...
        advanced {
            htmlDomId: customer
        }
    )

    pageItem P10_CUSTOMER_ID (
        type: hidden
        // ...
        source {
            formRegion: @customer
            column: CUSTOMER_ID
            dataType: number
            // no primaryKey
        }
    )

    process save-customer (
        name: Process form Customer
        type: formAutoRowProcessing
        formRegion: @customer
        // ...
    )
)
Issues
LineColumnMessage
312Form is processed by a DML process but has no primary key item.

Compliant Solution - ★★★★★

page 10 (
    // ...
    region customer (
        name: Customer
        type: form
        // ...
        advanced {
            htmlDomId: customer
        }
    )

    pageItem P10_CUSTOMER_ID (
        type: hidden
        // ...
        source {
            formRegion: @customer
            column: CUSTOMER_ID
            dataType: number
            primaryKey: true
        }
    )

    process save-customer (
        name: Process form Customer
        type: formAutoRowProcessing
        formRegion: @customer
        // ...
    )
)

Tests

Test SQL query

select aa.workspace || '.' || aa.alias || '.' || r.page_id || '.' || coalesce(r.static_id, to_char(r.region_id)) as identifier,
       'Form ' || r.region_name || ' on page ' || r.page_id || ' of app ' || aa.alias || ' in ' || aa.workspace
         || ' is processed by a DML process but has no primary key item.' as message
  from apex_application_page_regions r
  join apex_applications aa
    on aa.application_id = r.application_id
       and aa.workspace = r.workspace
 where aa.workspace in (#ApexWorkspaces#)
   and r.source_type_code = 'NATIVE_FORM'
   and exists (select 1
                 from apex_application_page_proc p
                where p.application_id = r.application_id
                  and p.region_id = r.region_id
                  and p.process_type_code = 'NATIVE_FORM_DML')
   and not exists (select 1
                     from apex_application_page_items i
                    where i.application_id = r.application_id
                      and i.data_source_region_id = r.region_id
                      and i.is_primary_key = 'Yes')

Test results

IdentifierMessageMigration
WORKSPACE.CUSTOMERS.10.customerForm Customer on page 10 of app CUSTOMERS in WORKSPACE is processed by a DML process but has no primary key item.-

Parameters

Use parameters to customize the rule to your needs.

ParameterDescriptionDefault Value
ApexWorkspacesComma-separated List of APEX workspaces owning APEX applications to check.dblinter, dbl_gui

References