Отримайте поточне значення AUTO_INCREMENT для будь-якої таблиці


294

Як отримати поточне значення AUTO_INCREMENT для таблиці в MySQL?


31
Це питання не обов'язково є дублікатом. Пов'язане запитання запитує кількість рядків, і прийнята відповідь ТІЛЬКИ отримує кількість рядків, а не AUTO_INCREMENT - це зовсім інше питання.
methai

Відповіді:


568

Ви можете отримати всі дані таблиці за допомогою цього запиту:

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
що робити, якщо ви видалили останній запис? max не дасть тобі поточний auto_increment
peterpeterson

3
Чи дає це останнє значення AUTO_INCREMENT у таблиці або яке наступне значення буде?
sidx

18

Я вважаю, що ви шукаєте функцію LAST_INSERT_ID () MySQL . Якщо в командному рядку просто запустіть таке:

LAST_INSERT_ID();

Ви також можете отримати це значення за допомогою SELECT-запиту:

SELECT LAST_INSERT_ID();

3
Це не найкраща ідея, щоб додати її до неї і очікувати, це буде ідентифікатор наступного ряду. Тим часом інша транзакція може вставити новий рядок, і ви використовуєте неправильний ідентифікатор правильно?
agim

Ти маєш рацію. Я думаю, це залежить від середовища, в якому ви працюєте. Якщо це контрольоване тестове середовище, ви, швидше за все, можете додати його та бути в безпеці. Найкращу відповідь надав метай.
jvdub

2
Яка найкраща відповідь - залежить від того, чого ви хочете досягти. Якщо ви вставите новий рядок і хочете знати створений ідентифікатор, то ваша відповідь - найкраща відповідь, оскільки LAST_INSERT_ID () безпечний для транзакцій і забезпечує, ви отримаєте ідентифікатор для створеного об'єкта. Я проголосував за вашу відповідь, але я видалив би частину з "додати її до неї ..."
agim

25
LAST_INSERT_ID () - за з'єднання. Це означає, що якщо інший процес вставить за вами три додаткові рядки, ваш LAST_INSERT_ID () дзвінок буде іншим, ніж їхній. Це питання задає поточний значення AUTO_INC на самому столі.
methai

2
Якщо в останньому операторі INSERT вставлено більше одного рядка, це дасть неправильну відповідь. Документація MySQL (наголос додано): "LAST_INSERT_ID () повертає 64-бітове значення, що представляє перше автоматично створене значення, успішно вставлене в стовпець AUTO_INCREMENT в результаті останнього виконання виконавчого оператора INSERT." Інтуїтивно зрозумілий! dev.mysql.com/doc/refman/5.6/uk/…
Чарлі,

15

Якщо ви просто хочете дізнатися номер, а не отримувати його у запиті, ви можете використовувати:

SHOW CREATE TABLE tablename;

Ви повинні побачити auto_increment внизу


5
Схоже, це не працює, якщо у вашій таблиці немає рядків, а функція auto_increment знаходиться на 1.
Pacerier

6

Незважаючи на те , що відповідь methai є правильною, якщо ви вручну запускаєте запит, проблема виникає, коли 2 одночасні транзакції / з'єднання фактично виконують цей запит під час виконання (наприклад).

Щойно спробував вручну на MySQL Workbench з 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 () відразу після вставки! І ми можемо повторно використовувати цей ідентифікатор, щоб вставити його в інші таблиці, де очікується зовнішній ключ!

Крім того, ми не можемо виконати два запити наступним чином:

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

тому що насправді нам цікаво схопити / використати цей ідентифікатор в іншій таблиці або повернути його!


2
Гарне пояснення! Дякую. Тепер зрозуміло, чому б ми хотіли використовуватиlast_insert_id()
Імтіаз

Це цікавий сценарій, але я не думаю, що він насправді відповідає на питання про те, щоб отримати AUTO_INCREMENTзначення.
Шарліке

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 без підпису ):

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.