SERIAL and BIGSERIAL data types
Informix®
SERIAL
,
BIGSERIAL
data types to produce automatic integer sequences:SERIAL
can produce 32 bit integers (INTEGER
)BIGSERIAL
can produce 64 bit integers (BIGINT
)SERIAL8
is a synonym forBIGSERIAL
- Create the table with a column using
SERIAL
, orBIGSERIAL
. - To generate a new serial, no value or a zero value is specified in the
INSERT
statement:INSERT INTO tab1 ( c ) VALUES ( 'aa' ) INSERT INTO tab1 ( k, c ) VALUES ( 0, 'aa' )
- After
INSERT
, the new value of aSERIAL
column is provided insqlca.sqlerrd[2]
, while the new value of aBIGSERIAL
value must be fetched with aSELECT dbinfo('bigserial')
query.
Informix allows you to insert rows with a value
different from zero for a serial column. Using an explicit value will automatically increment the
internal serial counter, to avoid conflicts with future INSERT
statements that are
using a zero value:
SQL statement Internal serial counter
------------------------------------------------------------------------------------------
CREATE TABLE tab ( pkey SERIAL, name VARCHAR(50) ); 0
INSERT INTO tab VALUES ( 0, 'aaa' ); 1
INSERT INTO tab VALUES ( 10, 'bbb' ); 10
INSERT INTO tab VALUES ( 0, 'ccc' ); 11
DELETE FROM tab; 11
INSERT INTO tab VALUES ( 0, 'ddd' ); 12
Dameng®
IDENTITY(start,incr)
columns:CREATE TABLE tab ( k INTEGER IDENTITY(100,1), name VARCHAR(50) )
To get the last generated idetity value after an INSERT
, Dameng provides the
IDENTITY_CURRENT('tabname')
function.
IDENTITY
column, the SET
IDENTITY_INSERT
command must be used: SET IDENTITY_INSERT tab1 ON
INSERT INTO tab1 ( k, c ) VALUES ( 100, 'aaa' )
SET IDENTITY_INSERT tab1 OFF
On the next INSERT
not specifying the identity column, the new auto-incremented
value will be adapted to be greater than the largest value inserted by previous
INSERT
statements.
SEQUENCES
:CREATE SEQUENCE sq1 START WITH 100
seqname.nextval()
expression:INSERT INTO table VALUES ( sq1.nextval(), ... )
Solution
For best SQL portability when using different types of databases, consider using sequences as described in Solution 3: Use native SEQUENCE database objects.
To emulate Informix serials with Dameng, the ODI driver uses IDENTITY
columns.
In database creation scripts, all SERIAL[(n)]
data types must be converted by
hand to INTEGER IDENTITY[(n,1)]
data types, while BIGSERIAL[(n)]
data types must be converted by hand to BIGINT IDENTITY[(n,1)]
data types.
Tables created from the BDL programs can use the SERIAL
or BIGSERIAL data type:
When a BDL program executes a CREATE [TEMP] TABLE with such column type, the database interface
automatically converts to an identity column.
In BDL, the new generated SERIAL
value is available from the
sqlca.sqlerrd[2]
variable. The database interface performs a SELECT
IDENT_CURRENT('tabname')
. However, since
sqlca.sqlerrd[2]
is defined as an INTEGER
, it cannot hold values
from BIGINT
identity columns. When using a BIGINT IDENTITY
column,
retrieve the last generated serial with the IDENT_CURRENT()
SQL function.
By default, you cannot specify the identity column in INSERT
statements; All
INSERT
statements must be reviewed to remove the identity column from the list.
INSERT INTO tab (col1,col2) VALUES (0, p_value)
INSERT INTO tab (col2) VALUES (p_value)
INSERT
using records defined from the schema file (DEFINE rec
LIKE tab.*
) must also be reviewed:
INSERT INTO tab VALUES (rec.*) -- will use the serial column
INSERT INTO tab VALUES rec.* -- without parentheses, serial column is removed
Do not mix a serial emulation modes: Choose one of the provided serial
emulations for all the tables of the application database. Do note create the tables with a given
serial emulation, and later switch to another serial emulation for INSERT
statements. This is not supported.
dbi.database.dbname.ifxemul.datatype.serial = {
true|
false}
dbi.database.dbname.ifxemul.datatype.serial8 = {
true|
false}
dbi.database.dbname.ifxemul.datatype.bigserial = {
true|
false}
Disabling automatic serial retrieval for sqlca.sqlerrd[2]
For Informix compatibility, when the
SERIAL
type emulation is active, the ODI drivers automatically execute another SQL
query (or do a DB client API call when possible) after each INSERT
statement, to
get the last generated serial, and fill the sqlca.sqlerrd[2]
register. This results
in some overhead that can be avoided, if the sqlca.sqlerrd[2]
register is not used
by the program.
When serial emulation is required (to create temp tables with a serial column during program
execution), and the sqlca.sqlerrd[2]
register does not need to be filled,
(typically because you use your own method to retrieve the last generated serial), you can set the
ifxemul.datatype.serial.sqlerrd2
FGLPROFILE entry to false. This will avoid the
automatic retrieval of last serial value to fill sqlca.sqlerrd[2]
:
dbi.database.dbname.ifxemul.datatype.serial.sqlerrd2 = false
SERIAL
type emulation is
disabled with:dbi.database.dbname.ifxemul.datatype.serial = false
See also db_get_last_serial().