[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).
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:
- Comment sélectionner aléatoirement des lignes dans une table de bdd avec SQL
- Fonction pour convertir une date écrite en toutes lettres en une date de type date en SQL.
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
si id n est pas auto incrément comment on doit proceder
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.
Merci bcq pour cet article, il m’a tellement aidé.