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?

Amy Neville
la source
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
Copie possible de la ligne d'insertion PHP / MySQL, puis obtenez 'id'
Jim Fell
@ 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 .

Duncan Lock
la source
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.

Martin Sansone - MiOEE
la source
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).

Pilules d'explosion
la source
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?

PVR
la source
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'
);
Paulo A. Costa
la source
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)

MESepehr
la source
4

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

mojoken
la source
2

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

Arnav Singh
la source
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();

Olafnyr
la source
0

j'ai utilisé return $this->db->insert_id();pour Codeigniter

Hamza Saeed
la source
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.

Singh G
la source