Récupérer un ID auto-généré par GENERATED ALWAYS AS IDENTITY
Objectif :
Il est fortement recommandé d’ajouter un ID unique aux tables SQL.
Pour cela nous disposons, sur IBMi, des mots clefs : GENERATED ALWAS AS IDENTIFY.
Dans le code source de la talbe SQL à créer, la ligne suivante permet de définir un champs Identifiant unique qui sera entièrement géré par la machine.
MON_IDENTIFIANT_UNIQUE FOR COLUMN MON_ID BIGINT GENERATED ALWAYS AS IDENTITY NOT NULL
Lors des insertions dans la table, ce champ s’incrémentera tout seul automatiquement.
C’est très pratique.
Par contre, en SQL EMBEDDED, après un INSERT, il faut parfois récupérer la valeur de l’Identifiant autogénéré (pour l’utiliser en tant que clef secondaire dans l’ajout de lignes dans une seconde table, par exemple).
Pour cela, inutile de chercher à relire l’enregistrement inséré, il suffit d’utiliser : IDENTITY_VAL_LOCAL().
Une autre méthode (merci à Florian GRADOT de me l’avoir rappelée) consiste à utiliser FINAL TABLE.
Syntaxe :
Immédiatement après l’INSERT fait en SQL EMBEDDED, l’instruction SQL suivante permet de récupérer la valeur de l’identifiant utilisé lors de l’INSERT précédent.
EXEC SQL
VALUES IDENTITY_VAL_LOCAL() INTO :ma_variable_ID;
Ou
EXEC SQL
SELECT mon_champ_ID
INTO :ma_variable_ID
FROM FINAL TABLE (
INSERT INTO ma_table (mon_champ_1, mon_champ_x)
VALUES(‘ma_valeur_1’, ‘ma_valeur_x)
);
Exemples :
1 ) Création d’une table avec un Identifiant unique auto-généré :
CREATE TABLE MA_TABLE_SQL
FOR SYSTEM NAME MA_TABLE
(
MON_IDENTIFIANT_UNIQUE FOR COLUMN MON_ID BIGINT
GENERATED ALWAYS AS IDENTITY NOT NULL,
MON_CHAMP_1 FOR COLUMN FIELD_1 CHAR(3) NOT NULL,
MON_CHAMP_2 FOR COLUMN FIELD_2 CHAR(50) NOT NULL,
CONSTRAINT PK_MA_TABLE_ID
PRIMARY KEY( MON_CHAMP_1 )
)
RCDFMT MA_TABLEF;
La table MA_TABLE_SQL (MA_TABLE) contiendra le champ MON_IDENTIFIANT_UNIQUE (MON_ID).
Cet identifant sera géré automatiquement par SQL lors de l’insertion d’enregistrements dans la table.
2) Insertion d’un enregistrement en SQL EMBEDDED :
Dcl-s ma_variable_1 char(3) inz(‘FRA’);
Dcl-s ma_variable_2 char(50) inz(‘FRANCE’);
EXEC SQL
INSERT INTO MA_TABLE_SQL (MON_CHAMP_1, MON_CHAMP_2)
VALUES (:ma_variable_1, :ma_variable_2);
ma_variable_1 = ‘ESP’;
ma_varaibel_2 = ‘ESPAGNE’;
EXEC SQL
INSERT INTO MA_TABLE_SQL (MON_CHAMP_1, MON_CHAMP_2)
VALUES (:ma_variable_1, :ma_variable_2);
A l’exécution, 2 enregistrements seront ajoutés à la table.
SELECT * FROM MA_TABLE_SQL;
Le champs MON_IDENTIFANT_UNIQUE est bien auto-incrémenté.
Et cela sans avoir à spécifier quoique ce soit, en effet : le champs MON_IDENTIFANT_UNIQUE n’est pas utilsé dans l’INSERT.
3) Récupération de la valeur de l’identifiant auto-généré après un INSERT :
Dcl-s ma_variable_1 char(3) inz(‘FRA’);
Dcl-s ma_variable_2 char(50) inz(‘FRANCE’);
Dcl-s ma_variable_ID zoned(18: 0) inz;
EXEC SQL
INSERT INTO MA_TABLE_SQL (MON_CHAMP_1, MON_CHAMP_2)
VALUES (:ma_variable_1, :ma_variable_2);
// Récupération de la valeur attribuée à l’ID auto-généré lors de l’INSERT précédent
if SQLCODE >0;
EXEC SQL
VALUES IDENTITY_VAL_LOCAL() INTO :ma_variable_ID;
endif;
La variable ma_variable_ID contiendra la valeur du champ MON_IDENTIFIANT_UNIQUE attribué lors du dernier INSERT.
4) Récupération de la valeur de l’identifiant auto-généré avec FINAL TABLE :
Dcl-s ma_variable_1 char(3) inz(‘FRA’);
Dcl-s ma_variable_2 char(50) inz(‘FRANCE’);
Dcl-s ma_variable_ID zoned(18: 0) inz;
EXEC SQL
SELECT MON_IDENTIFIANT_UNIQUE
INTO :ma_variable_ID
FROM FINAL TABLE (
INSERT INTO MA_TABLE_SQL (MON_CHAMP_1, MON_CHAMP_2)
VALUES (:ma_variable_1, :ma_variable_2)
);
La variable ma_variable_ID contiendra la valeur du champ MON_IDENTIFIANT_UNIQUE attribué lors de l’INSERT.