Obtenir le nouvel ID de clé primaire d'enregistrement à partir de la requête d'insertion mysql?


249

Ok, alors disons que je fais un mysql INSERTdans une de mes tables et la table a la colonne item_idqui est définie sur autoincrementet primary key.

Comment puis-je obtenir la requête pour générer la valeur de la clé primaire nouvellement générée item_iddans la même requête?

Actuellement, j'exécute une deuxième requête pour récupérer l'id, mais cela ne semble pas être une bonne pratique, car cela pourrait produire le mauvais résultat ...

Si cela n'est pas possible, quelle est la meilleure pratique pour garantir que je récupère l'identifiant correct?


1
Il n'y a aucun moyen de renvoyer quoi que ce soit à partir d'une INSERTrequête comme celle-ci; pourquoi pensez-vous que cela pourrait produire un mauvais résultat?
Explosion Pills

4
Eh bien, si le processus est exécuté séparément par 2 personnes, vous pourriez obtenir une liste de processus qui se chevauchent, je pense - puisque vous devez exécuter 2 requêtes distinctes?
Amy Neville


@ JimFell oui c'est fondamentalement la même question, mais celle-ci a de bien meilleures réponses en général
RozzA

1
Utilisez postgresql puis faites comme ceci INSERT INTO table (col1, col2) VALUES (val1, val2) RETURNING id ou INSERT INTO table (col1, col2) VALUES (val1, val2) RETURNING * ou UPDATE table SET col1 = val1, col2 = val2 Instruction WHERE RETURNING id ou UPDATE table SET (col1, col2) = (val1, val2) WHERE instruction RETURNING id ou UPDATE table SET (col1, col2) = (val1, val2)
Instruction

Réponses:


327

Vous devez utiliser la LAST_INSERT_ID()fonction: http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

Par exemple:

INSERT INTO table_name (col1, col2,...) VALUES ('val1', 'val2'...);
SELECT LAST_INSERT_ID();

Cela vous ramènera la PRIMARY KEYvaleur de la dernière ligne que vous avez insérée:

L'ID qui a été généré est conservé sur le serveur par connexion . Cela signifie que la valeur renvoyée par la fonction à un client donné est la première valeur AUTO_INCREMENT générée pour la dernière instruction affectant une colonne AUTO_INCREMENT par ce client .

Par conséquent, la valeur renvoyée par LAST_INSERT_ID()est par utilisateur et n'est pas affectée par les autres requêtes qui pourraient s'exécuter sur le serveur à partir d'autres utilisateurs .


8
oui mais que se passe-t-il si dans l'intervalle (entre les requêtes dans la liste des processus) une autre ligne a été insérée? Existe-t-il un moyen d'écrire la requête d'insertion afin qu'elle génère cela?
Amy Neville

Ok, je vois ... le dernier identifiant d'insertion de la requête est enregistré même s'il n'est pas connecté dans le résultat ... $ mysqli-> insert_id
Amy Neville

27
Cela vous permettra de récupérer la PRIMARY KEYvaleur de la dernière ligne que vous avez insérée, car c'est par connexion - chaque connexion au serveur conservera sa propre valeur pour cela. J'ai mis à jour la réponse pour clarifier cela.
Duncan Lock

Supposons donc que 3 utilisateurs ont simultanément publié leurs formulaires et que ma base de données doit les saisir. Je veux ajouter une ligne correspondant à chaque ID nouvellement créé de table1 dans table2. La concurrence est-elle prise en charge ou devrai-je le faire manuellement en PHP pour les demandes d'écriture de base de données entrantes?
bad_keypoints

Si, au moment où vous effectuez l'insertion de table1, la base de données connaît toutes les informations que vous souhaitez insérer dans table2, vous pouvez utiliser un déclencheur pour ce faire ou les combiner dans une requête. Sinon, vous devrez utiliser plusieurs requêtes - c'est-à-dire le faire en PHP. Cela dépend de ce que sont les données et d'où elles proviennent pour la deuxième insertion.
Duncan Lock

21

IL FAUT SE MÉFIER !! de "LAST_INSERT_ID ()" si vous essayez de renvoyer cette valeur de clé primaire dans PHP.

Je sais que ce fil n'est pas étiqueté php, mais pour tous ceux qui sont tombés sur cette réponse qui cherchent à renvoyer un identifiant d'insertion MySQL à partir d'un insert PHP scripté en utilisant des appels mysql_query standard - cela ne fonctionnera pas et n'est pas évident sans capturer des erreurs SQL.

Le nouveau mysqli prend en charge plusieurs requêtes - dont LAST_INSERT_ID () est en fait une deuxième requête de l'original.

IMO un SELECT distinct pour identifier la dernière clé primaire est plus sûr que la fonction facultative mysql_insert_id () retournant l'ID AUTO_INCREMENT généré à partir de l'opération INSERT précédente.


7
LAST_INSERT_IDest une fonction MySQL par connexion. Si vous recherchez le dernier ID d'insertion, il est possible qu'une connexion distincte ait effectué une écriture et que vous ayez le mauvais ID.
Explosion Pills

@ExplosionPills mysql_insert_id()fonctionne également par connexion, mais il souffre également d'un comportement étrange comme on le voit ici stackoverflow.com/a/897374/1305910 dans le commentaire de Cliffordlife - nevermind nous aurions tous dû utilisermysqli
RozzA

pouvez-vous clarifier ce que vous voulez dire lorsque vous restez «ça ne marchera pas»?
john ktejik

18

De la LAST_INSERT_ID()documentation:

L'ID qui a été généré est conservé sur le serveur par connexion

C'est-à-dire que si vous avez deux requêtes distinctes pour le script simultanément, elles n'affecteront pas les unes des autres LAST_INSERT_ID()(sauf si vous utilisez une connexion persistante peut-être).


2
Je pense que c'est douteux si votre table a un déclencheur qui fait un insert dans une autre table .... LAST_INSERT_ID () renverra la valeur id de l'autre table ..
bgies

15

Voici ce que vous cherchez !!!

select LAST_INSERT_ID()

C'est la meilleure alternative de SCOPE_IDENTITY()fonction utilisée dans SQL Server.

Vous devez également garder à l'esprit que cela ne fonctionnera que s'il Last_INSERT_ID()est renvoyé par votre Insertrequête. Autrement dit, la requête renvoie l'ID inséré dans le schéma. Vous ne pouvez pas obtenir le dernier identifiant inséré d'une table spécifique.

Pour plus de détails, veuillez consulter le lien L'équivalent de la fonction SQLServer SCOPE_IDENTITY () dans mySQL?


6

Si vous avez besoin de la valeur avant d'insérer une ligne:

CREATE FUNCTION `getAutoincrementalNextVal`(`TableName` VARCHAR(50))
    RETURNS BIGINT
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN

    DECLARE Value BIGINT;

    SELECT
        AUTO_INCREMENT INTO Value
    FROM
        information_schema.tables
    WHERE
        table_name = TableName AND
        table_schema = DATABASE();

    RETURN Value;

END

Vous pouvez l'utiliser dans un encart:

INSERT INTO
    document (Code, Title, Body)
VALUES (                
    sha1( concat (convert ( now() , char), ' ',   getAutoincrementalNextval ('document') ) ),
    'Title',
    'Body'
);

1
Celui-ci ne semble pas être une bonne idée? Si 2 clients appellent cette fonction en même temps, ils penseront qu'ils insèrent le même identifiant alors qu'en réalité ils ne le sont pas .... l'un sera légèrement plus lent sur l'insert et obtiendra l'ID suivant sans le savoir.
CarCar

5

Vous recevrez ces paramètres sur le résultat de votre requête:

    "fieldCount": 0,
    "affectedRows": 1,
    "insertId": 66,
    "serverStatus": 2,
    "warningCount": 1,
    "message": "",
    "protocol41": true,
    "changedRows": 0

C'est insertIdexactement ce dont vous avez besoin.

(NodeJS-mySql)


4

Si en python en utilisant pymysql, à partir du curseur, vous pouvez utiliser cursor.lastrowid


2

utilisez simplement "$ last_id = mysqli_insert_id ($ conn);"


2
En fait, je suis tombé ici en cherchant la version php de cette réponse grâce à google, j'ai donc voté pour cette réponse. Bien que techniquement, l'OP n'ait pas demandé de php, cela pourrait être utile à beaucoup de gens qui trébuchent ici également.
Photographe Britt

Merci beaucoup Arnav! I
JuanSedano

1

Si vous utilisez PHP: Sur un objet PDO , vous pouvez simplement appeler la méthode lastInsertId après votre insertion.

Sinon, avec un LAST_INSERT_ID, vous pouvez obtenir la valeur comme ceci:SELECT LAST_INSERT_ID();



0

Je veux juste partager mon approche à ce sujet en PHP, certains d'entre vous ont peut-être trouvé que ce n'était pas un moyen efficace, mais c'est 100 fois mieux que les autres options disponibles.

générer une clé aléatoire et l'insérer dans le tableau en créant une nouvelle ligne. vous pouvez ensuite utiliser cette clé pour récupérer la clé primaire. utilisez la mise à jour pour ajouter des données et faire d'autres choses.

cela permet de sécuriser une ligne et d'avoir la bonne clé primaire.

Je ne le recommande vraiment que si vous n'avez pas d'autres options.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.