MySQL You can‘t specify target table ‘xxx‘ for update in FROM clause. 原因及解决方法
报错信息如下:
You can’t specify target table ‘xxxxxxxxxxxx’ for update in FROM clause
出问题的SQL
DELETE FROM table1 WHERE c1 IN ( SELECT table1.c1 FROM table1 inner join table2 on table1.id = table2.id WHERE c2 = 'xxxx' )
修改方案1(标准SQL方案):在where中包一层。
DELETE FROM table1 WHERE c1 IN ( select c1 from (SELECT table1.c1 FROM table1 inner join table2 on table1.id = table2.id WHERE c2 = 'xxxx') as t1 )
修改方案2(MySQL特有方案):采用MySQL专有语法
DELETE Table1,Table2 From table1 inner join table2 on table1.id = table2.id where table1.c1 = 'xxxx'
原因是什么呢?
1:、从错误信息的翻译:无法在FROM子句中为更新指定目标表。可以看出:FROM子句中的表,不能被改。
2、从修改方案上看,包一层之后,用了内部临时表。
(以下为个人猜测)
这条语句是,MySQL先对表上了读锁。而后update系列操作时,就无法加入写锁。所以报错了。
修改方案时:把查询出来的数据放在临时表空间中。这样就绕过这个问题了。
思考:
1、不要随意嵌套MySQL。(真浪费性能)
2、MySQL针对这个问题也推出了自己的解决方案。(从这个bug,也能看出MySQL的官方态度。就是不改bug。但是改问题。)