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

时间:2013-05-21 15:02:59

标签: mysql auto-increment

我正在使用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);

但它没有用。

4 个答案:

答案 0 :(得分:10)

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

以下是来自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。

答案 1 :(得分:3)

你在问题​​中说过

  

我的主要约束是我需要在单个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's answer也表明它没有必要,因为MySQL已经处理了自动增量值。无需手动执行MySQL已经执行的操作。

另请注意the first line in Bill's post

  

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

我写了crazy post explaining why in the DBA StackExchange

因此,您应该接受Bill's answer,因为最好的办法是什么都没有。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

为了响应@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]>