[SQL] Valeur de l’Identifiant de la dernière insertion

Lors de l’insertion d’une valeur dans une base de données nous avons souvent besoin de connaitre l’id (ou UID = identifiant unique) de la ligne que nous venons d’insérer.

Trop souvent nous pouvons voir la requête suivante:

SELECT MAX(id) FROM matable;

Même si le résultat peut être correct pour des bdd, où une seule ligne à la fois est insérée, il est fortement déconseillé de le faire pour des applications où de multiples insertions concurrentes peuvent avoir lieu en même temps (ce qui est en général courant lorsque l’on utilise une bdd).

En effet, si un traitement est un peu long on peut rapidement se retrouver à travailler avec les données d’un autre utilisateur sans s’en rendre compte!

Suivant les bdds utilisées ou langages utilisés différentes fonctions sont à notre disposition (Ex currval avec postgresql, lastinsertid avec php).

logo SQL server
Logo SQL Server 2008

SQL Server nous propose trois fonctions:

  • SCOPE_IDENTITY
    SELECT SCOPE_IDENTITY();
  • IDENTITY
    SELECT @@IDENTITY;
  • IDENT_CURRENT
    SELECT IDENT_CURRENT('matable');


SELECT @@IDENTITY;

@@IDENTITY renvoie la valeur du dernier auto incrément de la session en cours et ce quelque soit la table incrémentée.


SELECT SCOPE_IDENTITY();

SCOPE_IDENTITY() renvoie la valeur du dernier auto incrément de la session en cours dans l’étendu du code.


SELECT IDENT_CURRENT(‘matable’);

IDENT_CURRENT(‘matable’) renvoie la valeur du dernier auto incrément pour la table demandée. N’est pas limitée à la session en cours.
(Équivalent a un « SELECT Max(id) FROM table » )



Le résultat ne sera donc pas le même en fonction de la fonction utilisée.

Exemple

Soit deux tables A et B

CREATE TABLE tableA (idA INT IDENTITY (1,1) PRIMARY KEY, libelle nvarchar (50));
CREATE TABLE tableB (idB INT IDENTITY(1,1), libelle VARCHAR(10));
 
INSERT INTO tableA ('libelle') VALUES ('test');
 
INSERT INTO tableA ('libelle') VALUES ('test2');
 
INSERT INTO tableB ('libelle') VALUES ('test');
 
SELECT * FROM tableA;
SELECT SCOPE_IDENTITY();
 
/*=> Renvoie  ' 1 ' (de tableb). La dernière table sur laquelle il y a eu une insertion est bien la table b.*/
 
SELECT @@IDENTITY;
/*=> Renvoie  ' 1 ' (de tableb)'. Le code ci-dessus a été exécuté en une seule fois. La dernière insertion a été faite sur la table b.*/
 
SELECT IDENT_CURRENT('tableA');
 
/*=> Renvoie  ' 2 (de tablea)'. On demande spécifiquement la valeur de l'identifiant de la dernière ligne insérée dans la table A. */

Exemple 2 avec trigger

/*creation d'un trigger*/
/* Ce trigger va automatiquement créer l'insertion d'une ligne dans table b lorsque l'on écrit dans la table a. 
La valeur insérée dans la table b correspond d'ailleurs à la valeur du champs libellé dans la table a. */
 
CREATE TRIGGER triggerTableA ON tableA AFTER INSERT AS INSERT tableB SELECT inserted.libelle FROM inserted;
 
INSERT INTO tableA ('libelle') VALUES ('test3');
 
SELECT
@@IDENTITY AS [@@IDENTITY],
SCOPE_IDENTITY() AS [SCOPE_IDENTITY()],
IDENT_CURRENT('tableA') AS [ident_current_tableA],
IDENT_CURRENT('tableB') AS [ident_current_tableB];
 
/*
 
@@IDENTITY => '2' (de tableb).
// La dernière insertion qui a eu lieu dans la session en cours a été effectuée par le trigger dans la table b.
 
SCOPE_IDENTITY() => 3 (de tablea)
// La dernière insertion qui a eu lieu dans le code de la session en cours a été effectuée sur la table a. 
// Le trigger n'est pas pris en compte car il n'est pas directement écrit dans le code exécuté.
 
ident_current_tableA => 3 (de tablea)
// On demande spécifiquement la valeur de l'id de la table A.
 
ident_current_tableB => 2 (de tableb)
// On demande spécifiquement la valeur de l'id de la table B.
 
*/

Les trois fonctions renverront NULL si aucune insertion n’a eu lieu.
Donc attention a bien tester la valeur retour pour vos jointures et autres requêtes.

Pour en savoir plus http://msdn.microsoft.com/fr-fr/library/ms190315.aspx

(Testé sous sql server 2008).



Vous aurez peut être aussi envie de lire les articles suivant:

Points d’intérêt de cet article : SQL identifiant derniere insertion currval postgresql lastinsertid php IDENT_CURRENT SCOPE_IDENTITY @@IDENTITY

Mots clefs liés à cet article:

  • sql server récupérer dernier id
  • recuperer dernier id sql

5 commentaires sur « [SQL] Valeur de l’Identifiant de la dernière insertion »

  1. Bonjour, désolé pour le délai de réponse.
    Si votre id n’est pas en auto incrément vous devrez utiliser un système de lock sur la table au moment de l’insertion et récupération de l’id.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.