Voulez-vous le prochain identifiant ou l'identifiant de la ligne que vous insérez actuellement? Autrement dit, l'identifiant à la fin du code de paiement doit-il être l'identifiant de la ligne dans laquelle le code de paiement est stocké?
Mike
id de la ligne que
j'insère
6
Dans ce cas, concaténez les valeurs lorsque vous les récupérez, pas lorsque vous les insérez. C'est beaucoup plus facile de cette façon, et vous excluez le fait de se tromper d'ID, ou de devoir exécuter une mise à jour - pensez à ce qui se passerait si la ligne que vous venez d'insérer est demandée par un autre client, avant que la mise à jour ait eu la chance de s'exécuter: le client se retrouverait avec un code de paiement invalide. Sur un système à faible trafic, cela pourrait ne pas se produire, mais je ne vois pas l'intérêt de prendre le risque.
Merci pour les deux premières options ... Mais la troisième est juste le numéro deux appelé depuis PHP .. Je ne sais pas ce qui rend cela plus rapide sur les grandes bases de données ...
Gerard ONeill
1
@GerardONeill Supprimé
ravi404
3
car un cache est utilisé pour récupérer les données de information_schema.tables, cette solution ne fonctionne plus pour mysql 8.
Bruno
1
@Bruno pouvez-vous publier une référence?
mvorisek
1
Cet état officiel de la documentation qui TABLES.AUTO_INCREMENTest mis en cache dev.mysql.com/doc/refman/8.0/en/… . Le blog Mysql a également plusieurs articles à ce sujet, mais le système varaible qu'ils mentionnent semble obsolète: mysqlserverteam.com /
Bruno
50
Vous pouvez obtenir la prochaine valeur d'incrémentation automatique en faisant:
SHOW TABLE STATUS FROM tablename LIKE Auto_increment/*or*/SELECT`auto_increment`FROM INFORMATION_SCHEMA.TABLESWHERE table_name ='tablename'
Notez que vous ne devez pas l' utiliser pour modifier la table, utilisez plutôt une colonne auto_increment pour le faire automatiquement.
Le problème est qu'il last_insert_id()est rétrospectif et peut donc être garanti dans la connexion actuelle.
Ce bébé est potentiel et n'est donc pas unique par connexion et ne peut être invoqué.
Cela ne fonctionnerait que dans une seule base de données de connexion, mais les bases de données à connexion unique ont aujourd'hui l'habitude de devenir plusieurs bases de données de connexion demain.
Je ne l'ai pas contre-voté, mais le problème avec la tentative d'utilisation de la dernière valeur à incrémentation automatique est que ce n'est peut-être pas la dernière au moment où vous venez de l'utiliser - quelle que soit la rapidité avec laquelle SELECT et INSERT sont effectués.
Mike
@Mike, et si cela se faisait en une seule requête? Quelque chose comme insert into table_name (field1, field2) select 'constant', auto_increment from information_schema.tables where table_name = 'table_name'? J'utiliserais la mise à jour dans le after insertdéclencheur et last_insert_id(), bien que ...
binaryLV
1
@binaryLV: Plus l'écart entre SELECT et INSERT est petit, plus il y a de chances que la valeur ait changé, mais cela ne l'exclut pas complètement. Imaginez un système avec des milliers de visites par minute sur la base de données - les chances que la valeur ait changé augmentent considérablement. Le verrouillage de table ou de ligne peut empêcher cela s'il est effectué en une seule requête, mais cela repose sur un comportement particulier du moteur de base de données qui peut ne pas être bien documenté. J'irais avec une suite UPDATEsi j'avais aussi. Mais je préfère simplement concaténer les deux au moment de l'affichage et économiser tous les tracas.
Mike
3
SHOW TABLE STATUSs'attend à voir database nameaprès FROMet 'table name pattern'après LIKE.
x-yuri
2
car un cache est utilisé pour récupérer les données de information_schema.tables, cette solution ne fonctionne plus pour mysql 8.
Bruno
15
Cela renverra la valeur d'incrémentation automatique pour la base de données MySQL et je n'ai pas vérifié avec d'autres bases de données. Veuillez noter que si vous utilisez une autre base de données, la syntaxe de la requête peut être différente.
SELECT AUTO_INCREMENT FROM information_schema.tablesWHERE table_name ='your_table_name'and table_schema ='your_database_name';SELECT AUTO_INCREMENT FROM information_schema.tablesWHERE table_name ='your_table_name'and table_schema =database();
SELECT AUTO_INCREMENT FROM information_schema.tables WHERE nom_table = 'your_table_name' et table_schema = 'your_database_name';
LJay
10
La meilleure réponse utilise PHP MySQL_ pour une solution, je pensais que je partagerais une solution PHP MySQLi_ mise à jour pour y parvenir. Il n'y a pas de sortie d'erreur dans cet exemple!
$db = new mysqli('localhost','user','pass','database');$sql ="SHOW TABLE STATUS LIKE 'table'";$result=$db->query($sql);$row=$result->fetch_assoc();
echo $row['Auto_increment'];
Lance le prochain incrément automatique dans une table.
Gardez à l'esprit que la première méthode si l'enregistrement avec l'ID le plus élevé est supprimé, vous créerez alors un nouvel enregistrement avec l'ID que celui déposé avait l'habitude d'avoir.
Tom Jenkinson
et si la clé précédente a été utilisée dans une autre table et y est toujours conservée, vous pouvez vous retrouver avec une magie très étrange
Tebe
le premier renvoie un mauvais identifiant si vous déposez le dernier enregistrement inséré,
Ali Parsa
6
Solution:
CREATETRIGGER`IdTrigger` BEFORE INSERTON`payments`FOR EACH ROWBEGINSELECT AUTO_INCREMENT Into@xId
FROM information_schema.tables
WHERE
Table_SCHEMA ="DataBaseName"AND
table_name ="payments";SET NEW.`payment_code`= CONCAT("sahf4d2fdd45",@xId);END;
"DataBaseName" est le nom de notre base de données
La mise payment_codeà jour dans le after insertdéclencheur semble être la meilleure option.
binaryLV
3
Vous ne pouvez pas utiliser l'ID lors de l'insertion, vous n'en avez pas non plus besoin. MySQL ne connaît même pas l'ID lorsque vous insérez cet enregistrement. Vous pouvez simplement enregistrer "sahf4d2fdd45"dans le payment_codetableau et utiliser idet payment_codeplus tard.
Si vous avez vraiment besoin que votre code de paiement contienne l'ID, METTEZ à JOUR la ligne après l'insertion pour ajouter l'ID.
+1 Pour rendre cela un peu plus explicite: si vous récupérez la «dernière» valeur d'une colonne, il est garanti qu'elle ne sera la dernière valeur qu'au moment exact où vous la saisissez. Il se peut que ce ne soit pas la dernière valeur lorsque vous utilisez cette valeur dans une insertion ultérieure. Dans le cas d'une colonne à incrémentation automatique, il est toujours possible qu'une autre valeur ait été ajoutée entre le moment où vous avez récupéré l'ID et le moment où vous l'insérez ailleurs. Si vous faites référence à une ligne que vous venez d'insérer, utiliser LAST_INSERT_ID () convient. Si vous essayez de garantir une valeur unique, ce n'est pas le cas.
Mike
@cularis, MySQL connaît le prochain identifiant d'auto_increment, il est répertorié dans le information_schema.tablestableau.
Johan
1
@faressoft: Si l'idée est d'avoir un code de paiement qui comprend une chaîne unique plus l'ID de la ligne qui contient ce code de paiement, combinez simplement les deux lorsque vous récupérez la ligne - soit avec un SELECT ... CONCAT(payment_code, id), soit dans votre code d'application. Vous pouvez même encapsuler le SELECTdans un VIEW, afin de toujours renvoyer la bonne valeur, sans vous soucier du CONCAT dans chaque SELECT de votre application.
Mike
3
Pourquoi avez-vous besoin du prochain ID incrémentiel?
MySQL n'autorise qu'un champ auto-incrémenté par table et il doit également être la clé primaire pour garantir l'unicité.
Notez que lorsque vous obtenez le prochain ID d'insertion, il peut ne pas être disponible lorsque vous l'utilisez, car la valeur que vous avez est uniquement dans la portée de cette transaction. Par conséquent, en fonction de la charge sur votre base de données, cette valeur peut être déjà utilisée au moment où la prochaine demande arrive.
Je vous suggère de revoir votre conception pour vous assurer que vous n'avez pas besoin de savoir quelle valeur d'incrémentation automatique attribuer ensuite
Ce n'est pas une bonne idée de supposer le type d'application qui nécessite l'ID. Il existe des applications comme celle sur laquelle je travaille en ce moment qui ont besoin du prochain ID incrémentiel et la valeur récupérée ne risque pas d'être allouée à un autre script.
JG Estiot
3
Je suggère de repenser ce que vous faites. Je n'ai jamais connu un seul cas d'utilisation où ces connaissances spéciales sont requises. L'identifiant suivant est un détail d'implémentation très spécial et je ne compte pas sur le fait qu'il soit sans danger pour l'ACID.
Faites une transaction simple qui met à jour votre ligne insérée avec le dernier identifiant:
BEGIN;INSERTINTO payments (date, item, method)VALUES(NOW(),'1 Month','paypal');UPDATE payments SET payment_code = CONCAT("sahf4d2fdd45", LAST_INSERT_ID())WHERE id = LAST_INSERT_ID();COMMIT;
Je peux dire un de ces cas d'utilisation, j'essaie de diagnostiquer un problème de production, donc je dois savoir si la dernière ligne d'une table est vraiment la dernière ligne ou s'il y en a eu une ajoutée après celle qui a été supprimée d'une manière ou d'une autre, table a un champ auto_increment dedans, donc en trouvant ces informations, je peux conclure si la ligne a été supprimée ou n'a jamais été ajoutée.
Usman
1
Cela pourrait peut-être fonctionner pour vous, mais je ne me fierais pas à cela car je ne pense pas que vous ayez une garantie à ce sujet: dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html " lorsque la colonne AUTO_INCREMENT fait partie d'un index à plusieurs colonnes), les valeurs AUTO_INCREMENT sont réutilisées si vous supprimez la ligne avec la plus grande valeur AUTO_INCREMENT dans un groupe. "
Markus Malkusch
Merci, des informations utiles, également selon votre lien partagé, auto_increment peut être réinitialisé en insérant manuellement un numéro, donc oui, pas fiable.
Usman
2
Vous devez vous connecter à MySQL et sélectionner une base de données avant de pouvoir le faire
$table_name ="myTable";$query = mysql_query("SHOW TABLE STATUS WHERE name='$table_name'");$row= mysql_fetch_array($query);$next_inc_value =$row["AUTO_INCREMENT"];
utilisez "mysql_insert_id ()". mysql_insert_id () agit sur la dernière requête effectuée, assurez-vous d'appeler mysql_insert_id () immédiatement après la requête qui génère la valeur.
Voici l'exemple d'utilisation:
<?php
$link = mysql_connect('localhost','username','password');if(!$link){
die('Could not connect: '. mysql_error());}
mysql_select_db('mydb');
mysql_query("INSERT INTO mytable VALUES('','value')");
printf("Last inserted record has id %d\n", mysql_insert_id());?>
Je suis moi aussi d’accord que c’est l’approche la plus simple. Je ne sais pas pourquoi vous avez voté à la baisse, mais je vais compenser par un vote favorable.
recurse le
Je n'ai pas mentionné la nécessité de la transaction, si vous ne l'enveloppez pas dans la transaction, ce code est moche dès que possible, il rencontre un chargement réel.
Tebe
1
Et si la dernière ligne était supprimée? Ou plusieurs dernières lignes ont-elles été supprimées?
Liam W
Non-problème, les clés libérées ne sont pas utilisées sauf si vous le spécifiez explicitement
Tebe
1
en utilisant la réponse de ravi404:
CREATEFUNCTION`getAutoincrementalNextVal`(`TableName` VARCHAR(50))
RETURNS BIGINT
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''BEGINDECLARE Value BIGINT;SELECT
AUTO_INCREMENT INTO Value
FROM
information_schema.tables
WHERE
table_name = TableName AND
table_schema =DATABASE();RETURN Value;END
en utilisant dans votre requête d'insertion, pour créer un hachage SHA1. ex.:
Cela fonctionne-t-il toujours? Y a-t-il des conditions de course si deux inserts se produisent en même temps?
Jmons
0
Amélioration de @ ravi404, au cas où votre décalage d'auto-incrémentation N'EST PAS 1:
SELECT(`auto_increment`-1)+ IFNULL(@@auto_increment_offset,1)FROM INFORMATION_SCHEMA.TABLES
WHERE table_name = your_table_name
AND table_schema =DATABASE();
( auto_increment-1): le moteur db semble toujours considérer un décalage de 1. Vous devez donc abandonner cette hypothèse, puis ajouter la valeur facultative de @@ auto_increment_offset, ou par défaut à 1: IFNULL (@@ auto_increment_offset, 1)
$auto_inc_db = mysql_query("SELECT * FROM my_table_name ORDER BY id ASC ");while($auto_inc_result = mysql_fetch_array($auto_inc_db)){$last_id =$auto_inc_result['id'];}$next_id =($last_id+1);
echo $next_id;//this is the new id,if auto increment ison
auto_increment
colonneRéponses:
Utilisez à
LAST_INSERT_ID()
partir de votre requête SQL.Ou
Vous pouvez également l'utiliser
mysql_insert_id()
pour l'obtenir en utilisant PHP.la source
LAST_INSERT_ID()
.mysqli_insert_id
Vous pouvez utiliser
ou si vous ne souhaitez pas utiliser information_schema, vous pouvez utiliser ceci
la source
TABLES.AUTO_INCREMENT
est mis en cache dev.mysql.com/doc/refman/8.0/en/… . Le blog Mysql a également plusieurs articles à ce sujet, mais le système varaible qu'ils mentionnent semble obsolète: mysqlserverteam.com /Vous pouvez obtenir la prochaine valeur d'incrémentation automatique en faisant:
Notez que vous ne devez pas l' utiliser pour modifier la table, utilisez plutôt une colonne auto_increment pour le faire automatiquement.
Le problème est qu'il
last_insert_id()
est rétrospectif et peut donc être garanti dans la connexion actuelle.Ce bébé est potentiel et n'est donc pas unique par connexion et ne peut être invoqué.
Cela ne fonctionnerait que dans une seule base de données de connexion, mais les bases de données à connexion unique ont aujourd'hui l'habitude de devenir plusieurs bases de données de connexion demain.
Voir:
SHOW TABLE STATUS
la source
insert into table_name (field1, field2) select 'constant', auto_increment from information_schema.tables where table_name = 'table_name'
? J'utiliserais la mise à jour dans leafter insert
déclencheur etlast_insert_id()
, bien que ...UPDATE
si j'avais aussi. Mais je préfère simplement concaténer les deux au moment de l'affichage et économiser tous les tracas.SHOW TABLE STATUS
s'attend à voirdatabase name
aprèsFROM
et'table name pattern'
aprèsLIKE
.Cela renverra la valeur d'incrémentation automatique pour la base de données MySQL et je n'ai pas vérifié avec d'autres bases de données. Veuillez noter que si vous utilisez une autre base de données, la syntaxe de la requête peut être différente.
la source
La meilleure réponse utilise PHP MySQL_ pour une solution, je pensais que je partagerais une solution PHP MySQLi_ mise à jour pour y parvenir. Il n'y a pas de sortie d'erreur dans cet exemple!
Lance le prochain incrément automatique dans une table.
la source
En PHP, vous pouvez essayer ceci:
OU
la source
Solution:
"DataBaseName" est le nom de notre base de données
la source
Une simple requête ferait l'affaire
SHOW TABLE STATUS LIKE 'table_name'
la source
Vous pouvez utiliser le déclencheur mysql
la source
payment_code
à jour dans leafter insert
déclencheur semble être la meilleure option.Vous ne pouvez pas utiliser l'ID lors de l'insertion, vous n'en avez pas non plus besoin. MySQL ne connaît même pas l'ID lorsque vous insérez cet enregistrement. Vous pouvez simplement enregistrer
"sahf4d2fdd45"
dans lepayment_code
tableau et utiliserid
etpayment_code
plus tard.Si vous avez vraiment besoin que votre code de paiement contienne l'ID, METTEZ à JOUR la ligne après l'insertion pour ajouter l'ID.
la source
information_schema.tables
tableau.SELECT ... CONCAT(payment_code, id)
, soit dans votre code d'application. Vous pouvez même encapsuler leSELECT
dans unVIEW
, afin de toujours renvoyer la bonne valeur, sans vous soucier du CONCAT dans chaque SELECT de votre application.Pourquoi avez-vous besoin du prochain ID incrémentiel?
MySQL n'autorise qu'un champ auto-incrémenté par table et il doit également être la clé primaire pour garantir l'unicité.
Notez que lorsque vous obtenez le prochain ID d'insertion, il peut ne pas être disponible lorsque vous l'utilisez, car la valeur que vous avez est uniquement dans la portée de cette transaction. Par conséquent, en fonction de la charge sur votre base de données, cette valeur peut être déjà utilisée au moment où la prochaine demande arrive.
Je vous suggère de revoir votre conception pour vous assurer que vous n'avez pas besoin de savoir quelle valeur d'incrémentation automatique attribuer ensuite
la source
Je suggère de repenser ce que vous faites. Je n'ai jamais connu un seul cas d'utilisation où ces connaissances spéciales sont requises. L'identifiant suivant est un détail d'implémentation très spécial et je ne compte pas sur le fait qu'il soit sans danger pour l'ACID.
Faites une transaction simple qui met à jour votre ligne insérée avec le dernier identifiant:
la source
Vous devez vous connecter à MySQL et sélectionner une base de données avant de pouvoir le faire
la source
utilisez "mysql_insert_id ()". mysql_insert_id () agit sur la dernière requête effectuée, assurez-vous d'appeler mysql_insert_id () immédiatement après la requête qui génère la valeur.
Voici l'exemple d'utilisation:
J'espère que l'exemple ci-dessus est utile.
la source
C'est tout :)
la source
Bien que je doute de sa productivité mais c'est 100% fiable
la source
en utilisant la réponse de ravi404:
en utilisant dans votre requête d'insertion, pour créer un hachage SHA1. ex.:
la source
Amélioration de @ ravi404, au cas où votre décalage d'auto-incrémentation N'EST PAS 1:
(
auto_increment
-1): le moteur db semble toujours considérer un décalage de 1. Vous devez donc abandonner cette hypothèse, puis ajouter la valeur facultative de @@ auto_increment_offset, ou par défaut à 1: IFNULL (@@ auto_increment_offset, 1)la source
Pour moi, cela fonctionne et semble simple:
la source
$last_id
répétitive quand vous pouvez justeDESC
. Votrewhile
bloc a fait des tonnes de travail inutile.Si vous ne renvoyez aucun AUTO_INCREMENT correct, essayez-le:
Ce cache vide pour la table, en BD
la source