Obtenir la valeur AUTO_INCREMENT actuelle pour n'importe quelle table

294

Comment obtenir la valeur AUTO_INCREMENT actuelle pour une table dans MySQL?

bparise
la source
31
Cette question n'est pas nécessairement un doublon. La question liée demande le nombre de lignes, et la réponse acceptée obtient UNIQUEMENT le nombre de lignes, PAS AUTO_INCREMENT - qui est une question entièrement différente.
methai

Réponses:

569

Vous pouvez obtenir toutes les données de table en utilisant cette requête:

SHOW TABLE STATUS FROM `DatabaseName` WHERE `name` LIKE 'TableName' ;

Vous pouvez obtenir exactement ces informations en utilisant cette requête:

SELECT `AUTO_INCREMENT`
FROM  INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'DatabaseName'
AND   TABLE_NAME   = 'TableName';
methai
la source
34
Peut également utiliser à la DATABASE()place du nom de base de données explicite.
M. Suleiman
22
Remarque: DATABASE () est NULL si vous n'avez pas émis de commande USE DATABASE
methai
5
Y a-t-il une raison pour laquelle vous ne pouvez pas SELECT MAX(id) FROM table_name?
Brian
43
que faire si vous avez supprimé le dernier enregistrement? max ne vous donnera pas l'actuel
auto_increment
3
Est-ce que cela donne la dernière valeur AUTO_INCREMENT dans le tableau ou quelle sera la valeur nnext?
sidx
18

Je crois que vous recherchez la fonction LAST_INSERT_ID () de MySQL . Si dans la ligne de commande, exécutez simplement ce qui suit:

LAST_INSERT_ID();

Vous pouvez également obtenir cette valeur via une requête SELECT:

SELECT LAST_INSERT_ID();
jvdub
la source
3
Ce n'est pas la meilleure idée d'y ajouter un et attendez-vous, ce sera l'ID de la ligne suivante. En attendant, une autre transaction pourrait insérer une nouvelle ligne et vous utiliseriez le mauvais ID, n'est-ce pas?
agim
Vous avez raison. Je suppose que cela dépend de l'environnement dans lequel vous travaillez. S'il s'agit d'un environnement de test contrôlé, vous pouvez très probablement en ajouter un et être en sécurité. La meilleure réponse a été fournie par methai.
jvdub
2
La meilleure réponse dépend de ce que vous souhaitez réaliser. Si vous insérez une nouvelle ligne et que vous souhaitez connaître l'ID créé, votre réponse est la meilleure réponse, car LAST_INSERT_ID () est sûr pour les transactions et garantit que vous obtenez l'ID de l'objet créé. J'ai voté votre réponse, mais je supprimerais la partie avec "ajoutez-en une ..."
agim
25
LAST_INSERT_ID () est par connexion. Cela signifie que si un autre processus insère trois lignes supplémentaires après vous, VOTRE appel LAST_INSERT_ID () sera différent du leur. Cette question demande la valeur AUTO_INC actuelle sur la table elle-même.
methai
2
Si la dernière instruction INSERT a inséré plusieurs lignes, cela vous donnera la mauvaise réponse. Documentation MySQL (non souligné dans l'original): "LAST_INSERT_ID () renvoie une valeur 64 bits représentant la première valeur générée automatiquement correctement insérée pour une colonne AUTO_INCREMENT à la suite de la dernière instruction INSERT exécutée." Intuitif! dev.mysql.com/doc/refman/5.6/en/…
Charlie
15

Si vous voulez simplement connaître le numéro, plutôt que de le récupérer dans une requête, vous pouvez utiliser:

SHOW CREATE TABLE tablename;

Vous devriez voir l'auto_increment en bas

johnnyjohnny
la source
5
Cela ne semble pas fonctionner si votre table n'a pas de lignes et si auto_increment est à 1.
Pacerier
6

Même si la réponse de methai est correcte si vous exécutez manuellement la requête, un problème se produit lorsque 2 transactions / connexions simultanées exécutent réellement cette requête au moment de l'exécution en production (par exemple).

Juste essayé manuellement dans MySQL Workbench avec 2 connexions ouvertes simultanément:

CREATE TABLE translation (
  id BIGINT PRIMARY KEY AUTO_INCREMENT
);
# Suppose we have already 20 entries, we execute 2 new inserts:

Transaction 1:

21 = SELECT `AUTO_INCREMENT` FROM INFORMATION_SCHEMA.TABLES
     WHERE TABLE_SCHEMA = 'DatabaseName' AND TABLE_NAME = 'translation';

insert into translation (id) values (21);

Transaction 2:

21 = SELECT `AUTO_INCREMENT` FROM INFORMATION_SCHEMA.TABLES
     WHERE TABLE_SCHEMA = 'DatabaseName' AND TABLE_NAME = 'translation';

insert into translation (id) values (21);

# commit transaction 1;
# commit transaction 2;

L'insertion de la transaction 1 est correcte: L'insertion de la transaction 2 va par erreur: Code d'erreur: 1062. Entrée en double '21' pour la clé 'PRIMARY'.

Une bonne solution serait la réponse de jvdub car par transaction / connexion les 2 insertions seront:

Transaction 1:

insert into translation (id) values (null);
21 = SELECT LAST_INSERT_ID();

Transaction 2:

insert into translation (id) values (null);
22 = SELECT LAST_INSERT_ID();

# commit transaction 1;
# commit transaction 2;

Mais nous devons exécuter la last_insert_id () juste après l'insertion! Et nous pouvons réutiliser cet identifiant pour être inséré dans d'autres tables où une clé étrangère est attendue!

De plus, nous ne pouvons pas exécuter les 2 requêtes comme suit:

insert into translation (id) values ((SELECT AUTO_INCREMENT FROM
    information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE()
    AND TABLE_NAME='translation'));

car nous sommes réellement intéressés à récupérer / réutiliser cet ID dans une autre table ou à revenir!

Davideas
la source
2
Bonne explication! Merci. Il est maintenant clair pourquoi voudrions-nous utiliserlast_insert_id()
Imtiaz
C'est un scénario intéressant, mais je ne pense pas qu'il réponde réellement à la question qui est de récupérer la AUTO_INCREMENTvaleur.
Sharlike
4

exemple de code exécutable mysqli:

<?php
    $db = new mysqli("localhost", "user", "password", "YourDatabaseName");
    if ($db->connect_errno) die ($db->connect_error);

    $table=$db->prepare("SHOW TABLE STATUS FROM YourDatabaseName");
    $table->execute();
    $sonuc = $table->get_result();
    while ($satir=$sonuc->fetch_assoc()){
        if ($satir["Name"]== "YourTableName"){
            $ai[$satir["Name"]]=$satir["Auto_increment"];
        }
    }
    $LastAutoIncrement=$ai["YourTableName"];
    echo $LastAutoIncrement;
?>  
Murat Başar
la source
1

Si la colonne est auto-incrémentée dans le serveur SQL, alors pour voir la valeur auto-incrémentée actuelle, et si vous souhaitez modifier cette valeur pour cette colonne, utilisez la requête suivante.

-- to get current value
select ident_current('Table_Name')

-- to update current value
dbcc checkident ('[Table_Name]',reseed,"Your Value")
Mukul
la source
1

Requête pour vérifier le pourcentage "d'utilisation" de AUTO_INCREMENT pour toutes les tables d'un schéma donné (sauf les colonnes de type bigint non signées ):

SELECT 
  c.TABLE_NAME,
  c.COLUMN_TYPE,
  c.MAX_VALUE,
  t.AUTO_INCREMENT,
  IF (c.MAX_VALUE > 0, ROUND(100 * t.AUTO_INCREMENT / c.MAX_VALUE, 2), -1) AS "Usage (%)" 
FROM 
  (SELECT 
     TABLE_SCHEMA,
     TABLE_NAME,
     COLUMN_TYPE,
     CASE 
        WHEN COLUMN_TYPE LIKE 'tinyint(1)' THEN 127
        WHEN COLUMN_TYPE LIKE 'tinyint(1) unsigned' THEN 255
        WHEN COLUMN_TYPE LIKE 'smallint(%)' THEN 32767
        WHEN COLUMN_TYPE LIKE 'smallint(%) unsigned' THEN 65535
        WHEN COLUMN_TYPE LIKE 'mediumint(%)' THEN 8388607
        WHEN COLUMN_TYPE LIKE 'mediumint(%) unsigned' THEN 16777215
        WHEN COLUMN_TYPE LIKE 'int(%)' THEN 2147483647
        WHEN COLUMN_TYPE LIKE 'int(%) unsigned' THEN 4294967295
        WHEN COLUMN_TYPE LIKE 'bigint(%)' THEN 9223372036854775807
        WHEN COLUMN_TYPE LIKE 'bigint(%) unsigned' THEN 0
        ELSE 0
     END AS "MAX_VALUE" 
   FROM 
     INFORMATION_SCHEMA.COLUMNS
     WHERE EXTRA LIKE '%auto_increment%'
   ) c

   JOIN INFORMATION_SCHEMA.TABLES t ON (t.TABLE_SCHEMA = c.TABLE_SCHEMA AND t.TABLE_NAME = c.TABLE_NAME)

WHERE
 c.TABLE_SCHEMA = 'YOUR_SCHEMA' 
ORDER BY
 `Usage (%)` DESC;
Jiří Chmiel
la source
0

Je cherchais la même chose et j'ai fini par créer une méthode statique à l'intérieur d'une classe Helper (dans mon cas, je l'ai nommée App \ Helpers \ Database).

La méthode

/**
 * Method to get the autoincrement value from a database table
 *
 * @access public
 *
 * @param string $database The database name or configuration in the .env file
 * @param string $table    The table name
 *
 * @return mixed
 */
public static function getAutoIncrementValue($database, $table)
{
    $database ?? env('DB_DATABASE');

    return \DB::select("
        SELECT AUTO_INCREMENT 
        FROM information_schema.TABLES 
        WHERE TABLE_SCHEMA = '" . env('DB_DATABASE') . "' 
        AND TABLE_NAME = '" . $table . "'"
    )[0]->AUTO_INCREMENT;
}

Pour appeler la méthode et obtenir le MySql AUTO_INCREMENT, utilisez simplement ce qui suit:

$auto_increment = \App\Helpers\Database::getAutoIncrementValue(env('DB_DATABASE'), 'your_table_name');

J'espère que ça aide.

McRui
la source