SQL portability / Auto-incremented columns (serials) |
The goal is to generate unique INTEGER or BIGINT numbers. These numbers will usually be used for primary keys.
A dedicated table named "SEQREG" is used to register sequence numbers. The key is the name of the sequence. This name will usually be the table name the sequence is generated for. In short, this table contains a primary key that identifies the sequence and a column containing the last generated number.
The uniqueness is granted by the concurrency management of the database server. The first executed instruction is an UPDATE that sets an exclusive lock on the SEQREG record. When two processes try to get a sequence at the same time, one will wait for the other until its transaction is finished.
The "fgldbutl.4gl" utility library implements a function called "db_get_sequence()" which generates a new sequence. You must create the SEQREG table as described in the fgldbutl.4gl source found in FGLDIR/src, and make sure that every user has the privileges to access and modify this table.
In order to guarantee the uniqueness of the generated number, the call to db_get_sequence() must be done inside a transaction block that includes the INSERT statement. Concurrent db sessions must wait for each other in case of conflict and the transaction isolation level must be high enough to make sure that the row of the sequence table will not be read or written by other db sessions until the transaction end.
IMPORT FGL fgldbutl DEFINE rec RECORD id INTEGER, name CHAR(100) END RECORD ... BEGIN WORK LET rec.id = db_get_sequence( "CUSTID" ) INSERT INTO CUSTOMER ( CUSTID, CUSTNAME ) VALUES ( rec.* ) COMMIT WORK