Nhận giá trị AUTO_INCREMENT hiện tại cho bất kỳ bảng nào


294

Làm cách nào để tôi nhận được giá trị AUTO_INCREMENT hiện tại cho một bảng trong MySQL?


31
Câu hỏi này không nhất thiết là một bản sao. Câu hỏi được liên kết là yêu cầu đếm số hàng và câu trả lời được chấp nhận CHỈ nhận được số hàng, KHÔNG TỰ ĐỘNG TỰ ĐỘNG - đó là một câu hỏi hoàn toàn khác.
methai

Câu trả lời:


569

Bạn có thể lấy tất cả dữ liệu bảng bằng cách sử dụng truy vấn này:

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

Bạn có thể nhận được chính xác thông tin này bằng cách sử dụng truy vấn này:

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

34
Cũng có thể sử dụng DATABASE()thay vì tên cơ sở dữ liệu rõ ràng.
M. Suleiman

22
Lưu ý: DATABASE () là NULL nếu bạn chưa ban hành lệnh SỬ DỤNG DATABASE
methai

5
Có một lý do bạn không thể SELECT MAX(id) FROM table_name?
Brian

43
Điều gì nếu bạn xóa hồ sơ cuối cùng? max sẽ không cung cấp cho bạn auto_increment hiện tại
peterpeterson

3
Điều này có cung cấp giá trị AUTO_INCREMENT mới nhất trong bảng không hoặc giá trị nnext sẽ là gì?
sidx

18

Tôi tin rằng bạn đang tìm kiếm hàm LAST_INSERT_ID () của MySQL . Nếu trong dòng lệnh, chỉ cần chạy như sau:

LAST_INSERT_ID();

Bạn cũng có thể có được giá trị này thông qua truy vấn CHỌN:

SELECT LAST_INSERT_ID();

3
Không phải là ý tưởng tốt nhất để thêm một cái vào đó và mong đợi, nó sẽ là ID của hàng tiếp theo. Trong thời gian đó, một giao dịch khác có thể chèn một hàng mới và bạn sẽ sử dụng ID sai phải không?
agim

Bạn đúng. Tôi đoán nó phụ thuộc vào môi trường bạn đang chạy. Nếu đó là môi trường kiểm tra được kiểm soát, thì rất có thể bạn có thể thêm một môi trường và an toàn. Câu trả lời tốt nhất được cung cấp bởi methai.
jvdub

2
Câu trả lời tốt nhất là gì, phụ thuộc vào những gì bạn muốn đạt được. Nếu bạn chèn một hàng mới và bạn muốn biết ID đã tạo, thì câu trả lời của bạn là câu trả lời tốt nhất, vì LAST_INSERT_ID () là giao dịch an toàn và đảm bảo, bạn nhận được ID cho đối tượng được tạo. Tôi đã bỏ phiếu cho câu trả lời của bạn nhưng tôi sẽ xóa phần đó bằng 'thêm một câu vào đó ...'
agim

25
LAST_INSERT_ID () là trên mỗi kết nối. Điều đó có nghĩa là, nếu một quy trình khác chèn thêm ba hàng sau bạn, cuộc gọi LAST_INSERT_ID () của bạn sẽ khác với cuộc gọi của họ. Câu hỏi này đang yêu cầu giá trị AUTO_INC hiện tại trên chính bảng.
methai

2
Nếu câu lệnh INSERT cuối cùng chèn nhiều hơn một hàng, điều này sẽ cho bạn câu trả lời sai. Tài liệu MySQL (nhấn mạnh thêm): "LAST_INSERT_ID () trả về giá trị 64 bit đại diện cho giá trị được tạo tự động đầu tiên được chèn thành công cho cột AUTO_INCREMENT do kết quả của câu lệnh INSERT được thực hiện gần đây nhất." Trực giác! dev.mysql.com/doc/refman/5.6/vi/ Kẻ
Charlie

15

Nếu bạn chỉ muốn biết số, thay vì lấy nó trong truy vấn thì bạn có thể sử dụng:

SHOW CREATE TABLE tablename;

Bạn sẽ thấy auto_increment ở phía dưới


5
Điều này dường như không hoạt động nếu bảng của bạn không có hàng và auto_increment đang ở 1.
Pacerier

6

Mặc dù câu trả lời của methai là chính xác nếu bạn chạy truy vấn theo cách thủ công, một sự cố xảy ra khi 2 giao dịch / kết nối đồng thời thực sự thực hiện truy vấn này khi chạy trong sản xuất (ví dụ).

Chỉ cần thử thủ công trong bàn làm việc của MySQL với 2 kết nối được mở đồng thời:

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

Giao dịch 1:

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

insert into translation (id) values (21);

Giao dịch 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;

Chèn giao dịch 1 là ok: Chèn giao dịch 2 gặp lỗi: Mã lỗi: 1062. Mục nhập trùng lặp '21' cho khóa 'CHÍNH HÃNG'.

Một giải pháp tốt sẽ là câu trả lời của jvdub vì mỗi giao dịch / kết nối, 2 lần chèn sẽ là:

Giao dịch 1:

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

Giao dịch 2:

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

# commit transaction 1;
# commit transaction 2;

Nhưng chúng ta phải thực thi last_insert_id () ngay sau khi chèn! Và chúng ta có thể sử dụng lại id đó để được chèn vào các bảng khác nơi dự kiến ​​sẽ có khóa ngoại!

Ngoài ra, chúng tôi không thể thực hiện 2 truy vấn như sau:

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

bởi vì chúng tôi thực sự quan tâm đến việc lấy / sử dụng lại ID đó trong bảng khác hoặc để trả về!


2
Lời giải thích hay! cảm ơn. Bây giờ rõ ràng lý do tại sao chúng tôi muốn sử dụnglast_insert_id()
Imtiaz

Đây là một kịch bản thú vị, nhưng tôi không nghĩ nó thực sự trả lời cho câu hỏi lấy lại AUTO_INCREMENTgiá trị.
Sharlike

4

mã mẫu thực thi 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

Nếu cột được tự động tăng trong máy chủ sql thì để xem giá trị tự động hiện tại và nếu bạn muốn chỉnh sửa giá trị đó cho cột đó, hãy sử dụng truy vấn sau.

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

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

1

Truy vấn để kiểm tra tỷ lệ phần trăm "sử dụng" của AUTO_INCREMENT cho tất cả các bảng của một lược đồ đã cho (trừ các cột có loại bigint không dấu ):

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

Tôi đã tìm kiếm tương tự và kết thúc bằng cách tạo một phương thức tĩnh bên trong lớp Trình trợ giúp (trong trường hợp của tôi, tôi đặt tên cho nó là App \ Helpers \ Database).

Phương pháp

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

Để gọi phương thức và nhận MySql AUTO_INCREMENT, chỉ cần sử dụng như sau:

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

Hy vọng nó giúp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.