Comment obtenir L'ID de la dernière ligne mise à jour dans MySQL?

Comment puis-je obtenir L'ID de la dernière ligne mise à jour dans MySQL en utilisant PHP?

116
demandé sur NikiC 2009-09-07 11:34:02

12 réponses

j'ai trouvé une réponse à ce problème :)

SET @update_id := 0;
UPDATE some_table SET column_name = 'value', id = (SELECT @update_id := id)
WHERE some_other_column = 'blah' LIMIT 1; 
SELECT @update_id;

MODIFIER par aefxx

cette technique peut être développée pour récupérer L'ID de chaque ligne affectée par une déclaration de mise à jour:

SET @uids := null;
UPDATE footable
   SET foo = 'bar'
 WHERE fooid > 5
   AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) );
SELECT @uids;

ceci renvoie une chaîne avec tous les ID concaténés par une virgule.

208
répondu Pomyk 2018-07-04 10:13:06

Hm, je suis surpris que parmi les réponses Je ne vois pas la solution la plus facile.

Suppose, item_id est une colonne d'identité entière dans items table et vous mettez à jour les lignes avec l'énoncé suivant:

UPDATE items
SET qwe = 'qwe'
WHERE asd = 'asd';

ensuite, pour connaître la dernière ligne affectée juste après la déclaration, vous devriez mettre légèrement à jour la déclaration dans le suivant:

UPDATE items
SET qwe = 'qwe',
    item_id=LAST_INSERT_ID(item_id)
WHERE asd = 'asd';
SELECT LAST_INSERT_ID();

si vous avez besoin de mettre à jour seulement vraiment changé row, vous devez ajouter une mise à jour conditionnelle de l'item_id par le biais de la dernière vérification de la date si les données vont changer dans la ligne.

29
répondu newtover 2018-08-27 17:22:03

c'est la même méthode que la réponse de Salman A, Mais voici le code dont vous avez réellement besoin pour le faire.

tout d'abord, éditez votre table de sorte qu'elle garde automatiquement la trace de chaque fois qu'une rangée est modifiée. Supprimer la dernière ligne si vous ne souhaitez savoir quand une ligne a été insérés.

ALTER TABLE mytable
ADD lastmodified TIMESTAMP 
    DEFAULT CURRENT_TIMESTAMP 
    ON UPDATE CURRENT_TIMESTAMP;

ensuite, pour connaître la dernière ligne mise à jour, vous pouvez utiliser ce code.

SELECT id FROM mytable ORDER BY lastmodified DESC LIMIT 1;

ce code est entièrement MySQL vs PostgreSQL: ajout d'une colonne "Last Modified Time" à une Table et manuel MySQL: tri des lignes . J'ai juste assemblé.

10
répondu Chad von Nau 2012-09-26 19:04:41

C'est officiellement simple mais remarquablement contre-intuitif. Si vous faites:

update users set status = 'processing' where status = 'pending' limit 1

Modifier pour ceci:

update users set status = 'processing' where status = 'pending' and last_insert_id(user_id) limit 1

l'ajout de last_insert_id(user_id) dans la clause where indique MySQL à set sa variable interne à L'ID de la rangée trouvée. Quand vous passez une valeur à last_insert_id(expr) comme ceci, il finit par retourner cette valeur, qui dans le cas d'IDs comme ici est toujours un entier positif et donc évalue toujours à vrai, ne jamais interférer avec la clause où. Cela ne fonctionne que si une rangée a été réellement trouvée, alors n'oubliez pas de vérifier les rangées affectées. Vous pouvez alors obtenir la carte D'identité de plusieurs façons.

MySQL last_insert_id()

vous pouvez générer des séquences sans appeler LAST_INSERT_ID (), mais le l'utilité d'utiliser la fonction de cette façon est que la valeur ID est maintenu dans le serveur comme la dernière valeur générée automatiquement. Il est multi-utilisateur sûr parce que plusieurs clients peuvent émettre la mise à jour instruction et obtenir leur propre valeur de séquence avec L'instruction SELECT (ou mysql_insert_id()), sans affecter ou être affectés par d'autres clients qui génèrent leurs propres valeurs de séquence.

MySQL mysql_insert_id()

retourne la valeur générée pour une colonne AUTO_ incrément par précédente instruction INSERT ou UPDATE. Utilisez cette fonction après avoir réalisé un INSERT statement dans un tableau qui contient Champ AUTO_ incrément, ou ont utilisé INSERT ou UPDATE pour définir une colonne valeur avec LAST_INSERT_ID (expr).

la raison des différences entre LAST_INSERT_ID () et mysql_insert_id() est que LAST_INSERT_ID() est rendu facile à utiliser dans scripts alors que mysql_insert_id() essaie de fournir plus exacte informations sur ce qui arrive à la colonne AUTO_ incrément.

PHP mysqli_insert_id()

effectuant un INSERT ou une déclaration de mise à jour à l'aide de LAST_INSERT_ID() la fonction modifiera également la valeur retournée par mysqli_insert_id() fonction.

Mettre tous ensemble:

$affected_rows = DB::getAffectedRows("
    update users set status = 'processing' 
    where status = 'pending' and last_insert_id(user_id) 
    limit 1"
);
if ($affected_rows) {
    $user_id = DB::getInsertId();
}

(pour information) la classe DB est ici .)

8
répondu Vladimir Kornea 2017-11-01 05:15:55

Requête :

$sqlQuery = "UPDATE 
            update_table 
        SET 
            set_name = 'value' 
        WHERE 
            where_name = 'name'
        LIMIT 1;";

fonction PHP:

function updateAndGetId($sqlQuery)
{
    mysql_query(str_replace("SET", "SET id = LAST_INSERT_ID(id),", $sqlQuery));
    return mysql_insert_id();
}

C'est un travail pour moi ;)

5
répondu GigolNet Guigolachvili 2014-05-01 16:48:34

Hé, j'avais juste besoin d'un tel tour - je l'ai résolu d'une manière différente, peut-être que ça marchera pour vous. Remarque ce n'est pas une solution évolutive et sera très mauvais pour les grands ensembles de données.

divisez votre requête en deux parties -

tout d'abord, sélectionnez l'id de lignes que vous souhaitez mettre à jour et de les stocker dans une table temporaire.

deuxièmement, faire la mise à jour Originale avec la condition dans la déclaration de mise à jour changé à where id in temp_table .

et pour assurer la simultanéité, vous devez verrouiller la table avant ces deux étapes et puis relâcher la serrure à la fin.

encore une fois, cela fonctionne pour moi, pour une requête qui se termine par limit 1 , donc je n'utilise même pas une table temp, mais simplement une variable pour stocker le résultat du premier select .

je préfère cette méthode car je sais que je vais toujours mettre à jour une seule ligne, et le code est simple.

2
répondu olamundo 2009-12-27 17:55:34

ID de la dernière ligne mise à jour est le même ID que vous utilisez dans la 'updateQuery' pour trouver et mettre à jour cette ligne. Donc, il suffit de sauver (appel) que L'identification sur tout ce que vous voulez.

last_insert_id() dépend du AUTO_INCREMENT , mais pas de la dernière mise à jour.

2
répondu Driada 2014-01-24 01:18:49

pour en savoir plus sur la réponse acceptée ci-dessus

pour ceux qui se demandaient := & =

différence significative entre := et = , c'est-à-dire que := fonctionne en tant qu'opérateur d'assignation de variables partout, tandis que = ne fonctionne que de cette façon dans les instructions, et est un opérateur de comparaison partout ailleurs.

So SELECT @var = 1 + 1; laissera @var inchangé et retournera un booléen (1 ou 0 selon la valeur actuelle de @var), tandis que SELECT @var := 1 + 1; changera @var en 2 , et retour 2 . [Source]

2
répondu Anon30 2017-05-23 12:09:59

si vous ne faites que des insertions, et que vous en voulez une de la même session, faites comme la réponse de peirix. Si vous faites des modifications, vous aurez besoin de modifier votre schéma de base de données pour stocker quelle entrée a été la plus récente mise à jour.

si vous voulez l'id de la dernière modification, qui peut avoir été faite à partir d'une session différente (c'est-à-dire pas celle qui vient d'être faite par le code PHP en cours d'exécution, mais celle qui est faite en réponse à une requête différente), vous pouvez ajouter un Colonne TIMESTAMP de votre table appelée last_modified (voir http://dev.mysql.com/doc/refman/5.1/en/datetime.html pour information), puis lorsque vous mettez à jour, définissez last_modified=CURRENT_TIME.

ayant défini ceci, vous pouvez alors utiliser une requête comme: Sélectionnez id dans l'ordre du tableau par last_modified DESC LIMIT 1; pour obtenir la rangée la plus récemment modifiée.

1
répondu a1kmm 2009-09-07 08:06:53
SET @uids := "";
UPDATE myf___ingtable
   SET id = id
   WHERE id < 5
  AND ( SELECT @uids := CONCAT_WS(',', CAST(id AS CHAR CHARACTER SET utf8), @uids) );
SELECT @uids;

j'ai dû lancer la carte d'identité (Je ne sais pas pourquoi)... ou je ne peux pas obtenir le contenu @uids (c'était un blob) Merci beaucoup pour Pomyk réponse!

1
répondu Gromish 2012-02-23 17:46:18

ma solution est, d'abord décider le "id" ( @uids ) avec la commande select et après mettre à jour ce id avec @uids .

SET @uids := (SELECT id FROM table WHERE some = 0 LIMIT 1);
UPDATE table SET col = 1 WHERE id = @uids;SELECT @uids;

ça a marché sur mon projet.

0
répondu Ahmet Uğur 2016-01-11 02:33:47

pas besoin d'autant de code Mysql. En PHP, la requête devrait ressembler à quelque chose comme ceci:

$updateQuery = mysql_query("UPDATE table_name SET row='value' WHERE id='$id'") or die ('Error');
$lastUpdatedId = mysql_insert_id();
-8
répondu Driada 2013-06-06 12:19:29