繁体   English   中英

使用子查询mysql在同一个表中更改auto_increment

[英]change auto_increment within same table using subquery mysql

我正在使用mysql。 我有一个带auto_increment计数器集的数据库表。 现在因为一个要求我需要离开100个ID并从101开始移动所有现有记录,所以当前id 1将变为101,id 2将变为102,依此类推。

我能够将记录移动到101,但问题是如何将auto_increment计数器更改为max(id)+1。

这里的主要约束是我需要在单个sql语句中执行它。 我无法使用@counter保存该值并在以后使用它。

我尝试使用以下查询

ALTER TABLE role AUTO_INCREMENT = (SELECT rd.counter FROM (SELECT (MAX(id) + 1) AS counter FROM role r) rd);

但它没有用。

解析器不支持您尝试使用它的位置的子查询。

这是MySQL源代码的摘录,来自sql / sql_yacc.yy:

create_table_option:
    . . .
    | AUTO_INC opt_equal ulonglong_num

您应该阅读的内容是AUTO_INCREMENT表选项只接受单个文字编号,而不接受表达式或子查询或变量或其他任何内容。 因此,您无法在执行SELECT MAX(id)+1的同一语句中设置AUTO_INCREMENT。

但你没必要。

MySQL绝不会分配小于当前表中最大值的自动增量ID。 因此,如果您有一个id值为102的表,则分配的下一个值至少为 103。

您甚至可以尝试明确设置AUTO_INCREMENT = 50,但会自动增加到MAX(id)+1。

你在问题中说过

这里的主要约束是我需要在单个sql语句中执行它。 我无法使用@counter保存该值并在以后使用它。

实际上,您可以尝试使用动态SQL,看看它是否工作如下:

SELECT (MAX(id) + 1) INTO @counter FROM role;
SET @sql = CONCAT('ALTER TABLE role AUTO_INCREMENT=',@counter);
PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;

这可能有效,也可能无效。 即使它对您有用Bill Karwin的回答也表明它没有必要,因为MySQL已经处理了自动增量值。 无需手动执行MySQL已经执行的操作。

另请注意Bill的帖子中的第一行

解析器不支持您尝试使用它的位置的子查询。

我写了一篇疯狂的帖子,解释了为什么在DBA StackExchange中

因此,你应该接受比尔的回答,因为最好的办法就是什么都没有。

根据maual( http://dev.mysql.com/doc/refman/5.5/en/example-auto-increment.html ),当您在auto_increment字段中手动插入或更改值时,auto_increment值将自动调整。

所以在给你的记录后新的id = id + 100你不再需要关心auto_increment值......

为响应@Peter,在更改现有值后,您似乎必须更新AUTO_INCREMENT值。 以下示例在MariaDB 10.0.12上完成:

MariaDB [test]> show create table m;
+-------+--------------------------------------------------------+
| Table | Create Table                                           |
+-------+--------------------------------------------------------+
| m     | CREATE TABLE `m` (                                     |
|       |`id` int(10) unsigned NOT NULL AUTO_INCREMENT,          |
|       |`t` varchar(10) NOT NULL DEFAULT '',                    |  
|       |PRIMARY KEY (`id`)                                      |
|       |) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+--------------------------------------------------------+
1 row in set (0.00 sec)

MariaDB [test]> insert into m (t) values ('a'),('b');
Query OK, 2 rows affected (0.03 sec)
Records: 2  Duplicates: 0  Warnings: 0

MariaDB [test]> select * from m;
+----+---+
| id | t |
+----+---+
|  1 | a |
|  2 | b |
+----+---+
2 rows in set (0.00 sec)

MariaDB [test]> update m set id=id+10;
Query OK, 2 rows affected (0.05 sec)
Rows matched: 2  Changed: 2  Warnings: 0

MariaDB [test]> select * from m;
+----+---+
| id | t |
+----+---+
| 11 | a |
| 12 | b |
+----+---+
2 rows in set (0.00 sec)

MariaDB [test]> show create table m;
+-------+--------------------------------------------------------+
| Table | Create Table                                           |
+-------+--------------------------------------------------------+
| m     | CREATE TABLE `m` (                                     |
|       |`id` int(10) unsigned NOT NULL AUTO_INCREMENT,          |
|       |`t` varchar(10) NOT NULL DEFAULT '',                    |  
|       |PRIMARY KEY (`id`)                                      |
|       |) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 |
+-------+--------------------------------------------------------+
1 row in set (0.00 sec)

MariaDB [test]> insert into m (t) values ('c');
Query OK, 1 row affected (0.04 sec)

MariaDB [test]> select * from m;
+----+---+
| id | t |
+----+---+
|  3 | c |
| 11 | a |
| 12 | b |
+----+---+
3 rows in set (0.00 sec)

MariaDB [test]>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM