获取任何表的当前 AUTO_INCREMENT 值

Posted

技术标签:

【中文标题】获取任何表的当前 AUTO_INCREMENT 值【英文标题】:Get current AUTO_INCREMENT value for any table 【发布时间】:2013-03-27 03:17:01 【问题描述】:

如何获取 mysql 中表的当前 AUTO_INCREMENT 值?

【问题讨论】:

这个问题不一定是重复的。链接的问题要求行数,而接受的答案仅获得行数,而不是 AUTO_INCREMENT - 这是一个完全不同的问题。 【参考方案1】:

列出 dbname 所有的 tabename 和 AUTO_INCREMENT

SELECT `AUTO_INCREMENT`,`TABLE_NAME`
FROM  INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'dbname' ORDER BY AUTO_INCREMENT desc

【讨论】:

【参考方案2】:

即使如果您手动运行查询,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。密钥“PRIMARY”的条目“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()! 我们可以重用该 id 以插入到其他需要外键的表中!

此外,我们无法执行以下 2 个查询:

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

因为我们实际上有兴趣在其他表中获取/重用该 ID 或返回!

编辑:2021 年 2 月 8 日,检索值

要实际检索应用程序中的值(在 Java 中使用 MyBatis 完成的示例):

@Mapper
public interface ClientMapper 
    @Select("select last_insert_id()")
    Long getLastInsertedId();

    @Insert(...)
    void insertClientInfo(ClientInfo client);

然后在存储库中

public void insertClientInfo(ClientInfo clientInfo) 
    mapper.insertClientInfo(clientInfo);
    Long pk = mapper.getLastInsertedId();
    clientInfo.setId(pk);

【讨论】:

很好的解释!谢谢。现在很清楚我们为什么要使用last_insert_id() 这是一个有趣的场景,但我认为它并不能真正回答检索AUTO_INCREMENT 值的问题。 @Sharlike,我添加了用法。【参考方案3】:

查询一个给定模式的所有表(除了类型为 bigint unsigned 的列)的 AUTO_INCREMENT 百分比“使用”:

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;

【讨论】:

【参考方案4】:

我一直在寻找相同的方法,最终在 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');

希望对你有帮助。

【讨论】:

【参考方案5】:

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

【讨论】:

你可以避免while循环: $table=$db->prepare("SHOW TABLE STATUS FROM YourDatabaseName where Name = 'YourTableName' ") ; $values= $table->get_result();返回 $values["Auto_increment"] ;【参考方案6】:

如果列在 sql server 中自动递增,那么要查看当前的自动递增值,如果要编辑该列的值,请使用以下查询。

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

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

【讨论】:

【参考方案7】:

您可以使用此查询获取所有表数据:

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

您可以通过使用此查询获得准确的信息:

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

【讨论】:

也可以使用DATABASE() 代替明确的数据库名称。 注意:如果您没有发出 USE DATABASE 命令,DATABASE() 为 NULL 你有什么理由不能SELECT MAX(id) FROM table_name 如果你删除了最后一条记录怎么办? max 不会给你当前的 auto_increment 这是否给出了表中最新的 AUTO_INCREMENT 值或 nnext 值将是什么?【参考方案8】:

如果您只想知道数字,而不是在查询中获取它,那么您可以使用:

SHOW CREATE TABLE tablename;

您应该在底部看到 auto_increment

【讨论】:

如果您的表没有行并且 auto_increment 位于 1,这似乎不起作用。【参考方案9】:

我相信您正在寻找 MySQL 的 LAST_INSERT_ID() 函数。如果在命令行中,只需运行以下命令:

LAST_INSERT_ID();

您也可以通过 SELECT 查询获得该值:

SELECT LAST_INSERT_ID();

【讨论】:

添加一个并期望它不是最好的主意,它将是下一行的 ID。与此同时,另一个事务可能会插入一个新行,而您会使用错误的 ID 对吗? 你是对的。我想这取决于你运行的环境。如果它是一个受控的测试环境,那么你很可能添加一个并且是安全的。 methai 提供了最佳答案。 最佳答案是什么,取决于您想要达到的目标。如果您插入新行并且想知道创建的 ID,那么您的答案就是最佳答案,因为 LAST_INSERT_ID() 是事务安全的,并确保您获得创建对象的 ID。我对你的答案投了赞成票,但我会删除带有“添加一个...”的部分 LAST_INSERT_ID() 是每个连接。这意味着,如果另一个进程在您之后插入三个额外的行,您的 LAST_INSERT_ID() 调用将与他们的不同。这个问题是询问表本身的当前 AUTO_INC val。 如果最后一个 INSERT 语句插入了多行,这会给你错误的答案。 MySQL 文档(已添加重点):“LAST_INSERT_ID() 返回一个 64 位值,表示作为最近执行的 INSERT 语句的结果,为 AUTO_INCREMENT 列成功插入的第一个自动生成的值。”直觉的! dev.mysql.com/doc/refman/5.6/en/…

以上是关于获取任何表的当前 AUTO_INCREMENT 值的主要内容,如果未能解决你的问题,请参考以下文章

如何插入或更新大量行(关于表的 auto_increment 值)

mysql 数据类型

MySQL 序列使用:使用 AUTO_INCREMENT获取AUTO_INCREMENT值

获取 SQLite 数据库的下一个 AUTO_INCREMENT 值

Java自学-JDBC 获取自增长id以及表的元数据

mysql中一些表选项