我试图更新某些行。我只想更新ID = 0的行。
我收到的错误消息是:
这是我正在使用的代码。欢迎任何建议!
UPDATE ch_15_posts SET ID = (select MAX(ID)+1 as max FROM `ch_15_posts`)
WHERE ID = 0
答案 0 :(得分:2)
MySQL不允许您从同一语句中的表中进行SELECT,在该语句中更新或删除同一个表。
mysql> UPDATE ch_15_posts SET ID = (select MAX(ID)+1 as max FROM `ch_15_posts`) where id = 0;
ERROR 1093 (HY000): You can't specify target table 'ch_15_posts' for update in FROM clause
有workaround做一种双子查询,它先评估内部子查询,并将结果存储在临时表中。但是,这不会得到你想要的,因为它只运行子子查询一次,它将生成一个值并将其分配给id = 0的所有行。
mysql> UPDATE ch_15_posts SET ID = (select max from (select MAX(ID)+1 as max FROM `ch_15_posts`) t) where id = 0;
Query OK, 3 rows affected (0.02 sec)
Rows matched: 3 Changed: 3 Warnings: 0
看起来您正在尝试将自动递增值分配给无意中设置值为0的行。您不能在不锁定表的情况下使用MAX(id)+1方法,因为其他并发会话可能是在你做的时候插入新的行。所以这是竞争条件。
但是,您可以通过使列成为自动增量键来原子地回填自动增量值。
演示:
mysql> create table c_15_posts (id int );
mysql> insert into c_15_posts values (0), (2), (0), (6), (0), (42);
Query OK, 6 rows affected (0.02 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> alter table c_15_posts modify id int auto_increment primary key;
Query OK, 6 rows affected (0.04 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> select * from c_15_posts;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 6 |
| 7 |
| 42 |
+----+
0的行不是从43开始,但它们确实接收唯一值。下一个插入将获得id 43。
答案 1 :(得分:1)
你可能需要这样的东西:
UPDATE ch_15_posts AS t1
JOIN (select MAX(ID)+1 as max FROM `ch_15_posts`) AS t2
SET t1.ID = t2.max
WHERE ID = 0