Uzyskaj bieżącą wartość AUTO_INCREMENT dla dowolnej tabeli


294

Jak uzyskać bieżącą wartość AUTO_INCREMENT dla tabeli w MySQL?


31
To pytanie niekoniecznie jest duplikatem. Połączone pytanie wymaga podania liczby wierszy, a zaakceptowana odpowiedź TYLKO otrzymuje liczbę wierszy, NIE AUTO_INCREMENT - co jest zupełnie innym pytaniem.
methai

Odpowiedzi:


568

Możesz uzyskać wszystkie dane z tabeli za pomocą tego zapytania:

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

Możesz uzyskać dokładnie te informacje za pomocą tego zapytania:

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

34
Można również użyć DATABASE()zamiast jawnej nazwy bazy danych.
M. Suleiman,

22
Uwaga: DATABASE () ma wartość NULL, jeśli nie wydano komendy USE DATABASE
methai

5
Czy istnieje powód, dla którego nie możesz SELECT MAX(id) FROM table_name?
Brian

43
co jeśli usunąłeś ostatni rekord? max nie poda aktualnego auto_increment
peterpeterson

3
Czy to daje najnowszą wartość AUTO_INCREMENT w tabeli lub jaka będzie następna wartość?
sidx,

18

Myślę, że szukasz funkcji LAST_INSERT_ID () MySQL . Jeśli w wierszu polecenia, po prostu uruchom następujące polecenie:

LAST_INSERT_ID();

Możesz również uzyskać tę wartość poprzez zapytanie SELECT:

SELECT LAST_INSERT_ID();

3
Nie jest najlepszym pomysłem, aby go dodać i oczekiwać, że będzie to identyfikator następnego wiersza. W międzyczasie inna transakcja może wstawić nowy wiersz i użyjesz niewłaściwego identyfikatora, prawda?
agim

Masz rację. Myślę, że zależy to od środowiska, w którym działasz. Jeśli jest to kontrolowane środowisko testowe, najprawdopodobniej możesz je dodać i być bezpiecznym. Najlepszą odpowiedź udzielił methai.
jvdub

2
Najlepsza odpowiedź zależy od tego, co chcesz osiągnąć. Jeśli wstawisz nowy wiersz i chcesz poznać utworzony identyfikator, twoja odpowiedź jest najlepszą odpowiedzią, ponieważ LAST_INSERT_ID () jest bezpieczny dla transakcji i zapewnia, że ​​otrzymasz identyfikator dla utworzonego obiektu. Głosowałem swoją odpowiedź w górę, ale chciałbym usunąć część z „dodasz do niego ...”
Agim

25
LAST_INSERT_ID () jest na połączenie. Oznacza to, że jeśli inny proces wstawi za tobą trzy dodatkowe wiersze, twoje wywołanie LAST_INSERT_ID () będzie inne niż ich. To pytanie dotyczy aktualnej wartości AUTO_INC w samej tabeli.
methai

2
Jeśli ostatnia instrukcja INSERT wstawiła więcej niż jeden wiersz, da to błędną odpowiedź. Dokumentacja MySQL (wyróżnienie dodane): „LAST_INSERT_ID () zwraca 64-bitową wartość reprezentującą pierwszą automatycznie wygenerowaną wartość pomyślnie wstawioną do kolumny AUTO_INCREMENT w wyniku ostatnio wykonanej instrukcji INSERT”. Intuicyjny! dev.mysql.com/doc/refman/5.6/en/…
Charlie

15

Jeśli chcesz tylko znać numer, a nie podawać go w zapytaniu, możesz użyć:

SHOW CREATE TABLE tablename;

Powinieneś zobaczyć auto_increment na dole


5
To nie wydaje się działać, jeśli tabela nie ma wierszy i auto_increment jest 1.
Pacerier

6

Chociaż odpowiedź methai jest poprawna, jeśli ręcznie uruchomisz zapytanie, problem pojawia się, gdy 2 współbieżne transakcje / połączenia faktycznie wykonują to zapytanie w środowisku wykonawczym (na przykład).

Właśnie wypróbowałem ręcznie w środowisku MySQL z 2 połączeniami otwartymi jednocześnie:

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

Transakcja 1:

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

insert into translation (id) values (21);

Transakcja 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;

Wstawianie transakcji 1 jest prawidłowe: Wstawianie transakcji 2 jest błędne: Kod błędu: 1062. Zduplikowany wpis „21” dla klucza „PODSTAWOWY”.

Dobrym rozwiązaniem byłaby odpowiedź jvdub , ponieważ dla każdej transakcji / połączenia 2 wstawki będą:

Transakcja 1:

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

Transakcja 2:

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

# commit transaction 1;
# commit transaction 2;

Ale musimy wykonać last_insert_id () zaraz po wstawieniu! I możemy ponownie użyć tego identyfikatora, aby wstawić go do innych tabel, w których oczekuje się klucza obcego!

Nie możemy również wykonać 2 zapytań w następujący sposób:

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

ponieważ tak naprawdę jesteśmy zainteresowani, aby pobrać / ponownie użyć tego identyfikatora w innej tabeli lub zwrócić!


2
Dobre wytłumaczenie! dzięki. Teraz jest jasne, dlaczego chcielibyśmy użyćlast_insert_id()
Imtiaz,

To ciekawy scenariusz, ale nie wydaje mi się, żeby faktycznie odpowiadał na pytanie, jakie jest odzyskanie AUTO_INCREMENTwartości.
Sharlike

4

Przykładowy kod wykonywalny 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;
?>  

1

Jeśli kolumna jest automatycznie zwiększana na serwerze SQL, to aby zobaczyć bieżącą automatycznie zwiększoną wartość, a jeśli chcesz edytować tę wartość dla tej kolumny, użyj następującego zapytania.

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

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

1

Zapytanie, aby sprawdzić procentowe „użycie” AUTO_INCREMENT dla wszystkich tabel jednego danego schematu (z wyjątkiem kolumn typu bigint bez znaku ):

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;

0

Szukałem tego samego i ostatecznie stworzyłem metodę statyczną wewnątrz klasy Helper (w moim przypadku nazwałem ją App \ Helpers \ Database).

Metoda

/**
 * 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;
}

Aby wywołać tę metodę i pobrać MySql AUTO_INCREMENT, wystarczy użyć:

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

Mam nadzieję, że to pomoże.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.