Lorsque je crée une seule ligne INSERT
dans une table comportant une AUTO_INCREMENT
colonne, j'aimerais utiliser la LAST_INSERT_ID()
fonction pour renvoyer la nouvelle AUTO_INCREMENT
valeur stockée pour cette ligne.
Comme de nombreux développeurs et administrateurs de Microsoft SQL Server savent sans doute que les fonctionnalités équivalentes dans SQL Server ( SCOPE_IDENTITY
et @@IDENTITY
) ne se sont pas déroulées sans problèmes .
Je connais l'état de la documentation MySQL:
L'ID généré est conservé sur le serveur connexion par connexion . Cela signifie que la valeur renvoyée par la fonction à un client donné est la première
AUTO_INCREMENT
valeur générée pour la dernière instruction affectant uneAUTO_INCREMENT
colonne de ce client . Cette valeur ne peut pas être affectée par d'autres clients, même s'ils génèrentAUTO_INCREMENT
leurs propres valeurs. Ce comportement garantit que chaque client peut récupérer son propre ID sans se préoccuper de l'activité des autres clients et sans avoir besoin de verrous ou de transactions.
et même aller jusqu'à dire:
L'utilisation simultanée de
LAST_INSERT_ID()
et deAUTO_INCREMENT
colonnes de plusieurs clients est parfaitement valide.
Existe-t-il des risques ou des scénarios connus pouvant entraîner le LAST_INSERT_ID()
non-retour de la valeur correcte?
J'utilise MySQL 5.5 sur CentOS 5.5 x64, Fedora 16 x64 et le moteur InnoDB.
Pour développer davantage le point 2 de la réponse donnée par DTest:
Sur les versions de MySQL que j'ai utilisées, il est judicieux de réinitialiser explicitement la valeur de LAST_INSERT_ID avant chaque bloc de code où vous prévoyez d'effectuer une insertion.
Cela peut être fait comme suit:
Une fois que la série d'instructions ci-dessus est exécutée, vous saurez si l'insertion a eu un effet en vérifiant si LAST_INSERT_ID était toujours défini sur "some_flag_init_value_of_your_choice" à la fin de l'exécution.
Sinon, vous pouvez vous retrouver avec la situation problématique suivante:
Étant donné que la deuxième insertion a échoué , vous vous attendiez peut-être à ce que le deuxième appel à LAST_INSERT_ID renvoie NULL ou produise un ensemble de résultats vide (zéro ligne). Le fait qu'il renvoie toujours un identifiant entier valide peut vous induire en erreur en pensant que le second insère SUCCEEDED alors qu'il ne l'a pas été.
Les choses deviennent EVEN WEIRDER si vous considérez que LAST_INSERT_ID continuera à conserver et à répéter le dernier identifiant unique réussi, même si des instructions d'insertion défaillantes ultérieures ciblent des tables différentes de la table ayant généré le dernier identifiant unique réussi. En d'autres termes, vous insérez dans la table TA et obtenez un identifiant de 5, puis vous insérez dans la TB (mais cela échoue), mais vous voyez toujours un 5. Sur cette base, vous pensez que vous venez de créer une nouvelle ligne dans TA avec id de 5 et une nouvelle ligne dans TB avec id de 5, alors qu'en réalité, il n'existe aucune ligne dans TB avec id de 5, ou bien il existe une telle ligne, mais elle n'a en réalité rien à voir avec le code que vous venez a couru.
la source
last_insert_id()
pour déterminer si une requête a abouti. C'est le dernier identifiant inséré après tout, contenant les valeurs dont vous avez besoin quand vous saviez déjà que vous aviez réussi.