Получить текущее значение AUTO_INCREMENT для любой таблицы


294

Как получить текущее значение AUTO_INCREMENT для таблицы в MySQL?


31
Этот вопрос не обязательно дубликат. Связанный вопрос запрашивает количество строк, а принятый ответ ТОЛЬКО получает количество строк, а НЕ AUTO_INCREMENT - это совершенно другой вопрос.
мая

Ответы:


569

Вы можете получить все данные таблицы, используя этот запрос:

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

Вы можете получить именно эту информацию, используя этот запрос:

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

34
Можно также использовать DATABASE()вместо явного имени базы данных.
М. Сулейман

22
Примечание: DATABASE () имеет значение NULL, если вы не ввели команду USE DATABASE
methai,

5
Есть ли причина, по которой ты не можешь SELECT MAX(id) FROM table_name?
Брайан

43
Что делать, если вы удалили последнюю запись? Макс не даст вам текущий auto_increment
peterpeterson

3
Дает ли это последнее значение AUTO_INCREMENT в таблице или каким будет значение nnext?
Sidx

18

Я считаю, что вы ищете функцию MySQL LAST_INSERT_ID () . Если в командной строке просто запустите следующее:

LAST_INSERT_ID();

Вы также можете получить это значение с помощью запроса SELECT:

SELECT LAST_INSERT_ID();

3
Это не лучшая идея, чтобы добавить один к нему и ожидать, что это будет идентификатор следующей строки. В то же время другая транзакция может вставить новую строку, и вы бы использовали неправильный идентификатор, верно?
Agim

Ты прав. Я предполагаю, что это зависит от среды, в которой вы работаете. Если это контролируемая среда тестирования, то вы, скорее всего, можете добавить ее и быть в безопасности. Лучший ответ был предоставлен methai.
jvdub

2
Какой лучший ответ, зависит от того, чего вы хотите достичь. Если вы вставите новую строку и хотите узнать созданный идентификатор, то ваш ответ - лучший ответ, поскольку LAST_INSERT_ID () безопасен для транзакций и гарантирует, что вы получите идентификатор для созданного объекта. Я проголосовал за ваш ответ, но я бы удалил часть с надписью «добавь к ней ...»
agim

25
LAST_INSERT_ID () для каждого соединения. Это означает, что если другой процесс вставит после вас три дополнительные строки, ваш вызов LAST_INSERT_ID () будет отличаться от их. Этот вопрос задает текущее значение AUTO_INC для самой таблицы.
мая

2
Если последний оператор INSERT вставил более одной строки, это даст вам неправильный ответ. Документация по MySQL (выделение выделено): «LAST_INSERT_ID () возвращает 64-разрядное значение, представляющее первое автоматически сгенерированное значение, успешно вставленное для столбца AUTO_INCREMENT в результате последнего выполненного оператора INSERT». Интуитивный! dev.mysql.com/doc/refman/5.6/en/…
Чарли

15

Если вы просто хотите узнать число, а не получить его в запросе, вы можете использовать:

SHOW CREATE TABLE tablename;

Вы должны увидеть auto_increment внизу


5
Это не работает, если в вашей таблице нет строк, а auto_increment имеет значение 1.
Pacerier

6

Даже если ответ methai будет правильным, если вы вручную запустите запрос, проблема возникает, когда 2 одновременных транзакции / соединения фактически выполняют этот запрос во время выполнения в производстве (например).

Только что попробовал вручную в MySQL верстак с 2 открытыми одновременно соединениями:

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

Транзакция 1:

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

insert into translation (id) values (21);

Транзакция 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;

Вставка транзакции 1 в порядке: вставка транзакции 2 завершается с ошибкой: Код ошибки: 1062. Дублирующая запись «21» для ключа «ПЕРВИЧНЫЙ».

Хорошим решением будет ответ jvdub , потому что для каждой транзакции / соединения 2 вставки будут:

Транзакция 1:

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

Транзакция 2:

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

# commit transaction 1;
# commit transaction 2;

Но мы должны выполнить last_insert_id () сразу после вставки! И мы можем повторно использовать этот идентификатор для вставки в другие таблицы, где ожидается внешний ключ!

Кроме того, мы не можем выполнить 2 запроса следующим образом:

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

потому что мы на самом деле заинтересованы, чтобы захватить / повторно использовать этот идентификатор в другой таблице или вернуть!


2
Хорошее объяснение! Спасибо. Теперь понятно, зачем нам это использоватьlast_insert_id()
Imtiaz

Это интересный сценарий, но я не думаю, что на самом деле он отвечает на вопрос о том, как получить AUTO_INCREMENTзначение.
Sharlike

4

Пример исполняемого кода 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

Если столбец автоинкрементирован на сервере sql, то для просмотра текущего автоинкрементного значения, и если вы хотите изменить это значение для этого столбца, используйте следующий запрос.

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

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

1

Запрос для проверки процентного «использования» AUTO_INCREMENT для всех таблиц одной данной схемы (кроме столбцов с типом bigint unsigned ):

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

Я искал то же самое и в итоге создал статический метод внутри класса Helper (в моем случае я назвал его App \ Helpers \ Database).

Метод

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

Чтобы вызвать метод и получить MySql AUTO_INCREMENT, просто используйте следующее:

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

Надеюсь, поможет.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.