AnyDAC
ContentsIndexHome
PreviousUpNext
Auto-Incremental Fields

AnyDAC supports correct appending of the new records with auto-incrementing fields and automatic refreshing of the database assigned values.

Group
Links
General

AnyDAC allows to insert a new record with an auto-incrementing column and get back a new value of this column. That works as for immediate updates, as for cached updates. Depending on a DBMS, the auto-incrementing fields may be implemented either using a special IDENTITY (or similar) column data type, either using a generator (or a sequence) and a table trigger:

DBMS 
Auto-incrementing column implementation 
Recognizing 
Advantage Database 
AUTOINC data type 
Automatic as auto-incrementing data type. 
Firebird / Interbase 
  • Generator and BEFORE INSERT trigger
  • Firebird 3.0: GENERATED BY DEFAULT AS IDENTITY
 
Automatic and manual specifying. See below. 
IBM DB2 
GENERATED AS IDENTITY data type 
Automatic as auto-incrementing data type. 
Informix 
SERIAL data type 
Automatic as auto-incrementing data type. 
MS Access 
COUNTER data type 
Automatic as auto-incrementing data type. 
MS SQL Server 
IDENTITY data type 
Automatic as auto-incrementing data type. 
MySQL 
AUTO_INCREMENT data type 
Automatic as auto-incrementing data type. 
Oracle 
Sequence and BEFORE INSERT FOR EACH ROW trigger 
Manual specifying. See below. 
PostgreSQL 
SERIAL data type 
Automatic as auto-incrementing data type. 
SQL Anywhere 
IDENTITY data type 
Automatic as auto-incrementing data type. 
SQLite 
INTEGER PRIMARY KEY AUTOINCREMENT data type 
Automatic as auto-incrementing data type. 
Sybase Adaptive Server Enterprise 
IDENTITY data type 
Automatic as auto-incrementing data type. 

 

Automatic recognition

AnyDAC automatically recognizes a column of an auto-incrementing data type, and defines it as dtIntXxx, [caAutoInc, caReadOnly, caAllowNull]. This leads to TField setup:

  • TField.DataType = ftAutoInc (TADAutoIncField) when dtInt32 or dtUInt32; otherwise one of the numeric ftXxxx data types;
  • TField.Required = False;
  • TField.ReadOnly = True;
  • TField.ProviderFlags = [pfInWhere], or [pfInWhere, pfInKey] when the column is part of a primary key.

AnyDAC automatically recognizes limited set of the Firebird auto-incrementing columns, and defines them as dtIntXxx, [caAutoInc, caAllowNull] when:

  • extended metadata is enabled;
  • a table has a BEFORE INSERT trigger;
  • the trigger depends on a single column and a single generator. This column is recognizing as auto-incrementing.

 

Manual specifying

For Oracle, other Firebird / Interbase cases, and other columns the auto-incrementing mode may be specified by programmer, using one of the options:

  • set UpdateOptions.AutoIncFields to the list of the auto-incrementing column names. When a column is of dtInt32 / dtUInt32 data type, then TADAutoIncField field will be created.
  • create an TADAutoIncField field at design or run time. The column must be of ftAutoInc / ftInteger / ftLongWord field type. For other data types consider to use data type mapping to TargetDataType = dtInt32.
  • set TField.AutoGenerateValue to arAutoInc for an auto-incrementing field. This method does not create TADAutoIncField, works with any field type, and may require additional field properties setup, eg setting ProviderFlags, Required and ReadOnly.

All these methods at end leads to TField.AutoGenerateValue = arAutoInc. 

 

Client auto-incrementing

By default AnyDAC uses the client side auto-incrementing for the auto-incrementing columns. After calling dataset Insert / Append method, the auto-incrementing column will get -1 value. With each next method call, the value will be incremented with the -1 (negative) step. That was made to distinguish the client assigned values and the DBMS assigned values. 

When UpdateOptions.RefreshMode <> rmManual, then after posting a new record the auto-incrementing column will get an actual positive value. 

The TADAutoIncField properties allows to adjust the client side auto-incrementing:

 

Client sequence filling

When a DBMS supports sequences or generators (here they are synonyms), then AnyDAC may fill an auto-incrementing column from a sequence on a client. This is alternative to client-side auto-incrementing. 

The auto-incrementing column must have pfInUpdate in TField.ProviderFlags and one of the UpdateOptions.FetchGeneratorsPoint values:

  • gpImmediate - a next value is fetched from a generator in TDataSet.Insert / Append method. And the value is already accessible in TDataSet.OnNewRecord event handler. When the TDataSet.Cancel method is called, then the value is lost.
  • gpDeferred - a next value is fetched in TDataSet.Post method.

Set the UpdateOptions.GeneratorName or TADAutoIncField.GeneratorName to a generator name, which will be used to get next sequence value. 

 

Universal setup

The following auto-incrementing column setup will work with any DBMS, including supporting native auto-incremental columns, and using sequences and triggers:

  • UpdateOptions.FetchGeneratorsPoint = gpNone. The client sequence filling is disabled.
  • not (pfInUpdate in TField.ProviderFlags). The column is excluded from INSERT / UPDATE clause.
  • fiMeta in FetchOptions.Items. The column, when it is possible is recognized as auto-incremental.

For Oracle, Firebird and Interbase is required to manually specify auto-incremental columns. For databases supporting native auto-incremental data types, no additional setup is required. But specifying will work in both cases. 

 

Master-detail handling

When master and detail datasets are linked by an auto-incrementing master column and cached updates is enabled, then consider to use Centralized Cached Updates mode with propagation of changes from master to detail datasets.

What do you think about this topic? Send feedback!