mysql在安全模式下删除

我有一个表教官,我想删除有一定范围内薪水的logging直观的方式是这样的:

delete from instructor where salary between 13000 and 15000; 

但是,在安全模式下,如果不提供主键(ID),则无法删除logging。

所以我写了下面的sql:

 delete from instructor where ID in (select ID from instructor where salary between 13000 and 15000); 

但是,有一个错误:

 You can't specify target table 'instructor' for update in FROM clause 

我很困惑,因为当我写

 select * from instructor where ID in (select ID from instructor where salary between 13000 and 15000); 

它不会产生错误。

我的问题是:

  1. 这个错误信息是什么意思,为什么我的代码是错的?
  2. 如何重写这个代码,使其在安全模式下工作?

谢谢!

谷歌search,stream行的答案似乎是“只是closures安全模式” :

 SET SQL_SAFE_UPDATES = 0; DELETE FROM instructor WHERE salary BETWEEN 13000 AND 15000; SET SQL_SAFE_UPDATES = 1; 

如果我说实话,我不能说我养成了安全模式的习惯。 尽pipe如此,我并不完全适应这个答案,因为它只是假设你应该在每次遇到问题时都更改数据库configuration。

因此,第二个查询更接近标记,但遇到了另一个问题:MySQL对子查询应用了一些限制,其中一个是在子查询中从中select表时不能修改表。

从MySQL手册引用, 对子查询的限制 :

通常,您不能修改表并从子查询中的同一个表中进行select。 例如,这个限制适用于以下forms的陈述:

 DELETE FROM t WHERE ... (SELECT ... FROM t ...); UPDATE t ... WHERE col = (SELECT ... FROM t ...); {INSERT|REPLACE} INTO t (SELECT ... FROM t ...); 

例外:如果您在FROM子句中使用子查询来修改表,则上述禁止不适用。 例:

 UPDATE t ... WHERE col = (SELECT * FROM (SELECT ... FROM t...) AS _t ...); 

这里FROM子句中的子查询的结果是作为一个临时表存储的,所以t中的相关行在t更新的时候已经被select了。

最后一点是你的答案。 在临时表中select目标ID,然后通过引用该表中的ID来删除:

 DELETE FROM instructor WHERE id IN ( SELECT temp.id FROM ( SELECT id FROM instructor WHERE salary BETWEEN 13000 AND 15000 ) AS temp ); 

SQLFiddle演示 。

你可以欺骗MySQL,以为你实际上是指定一个主键列。 这使您可以“覆盖”安全模式。

假设您有一个带有自动递增数字主键的表,您可以执行以下操作:

 DELETE FROM tbl WHERE id <> 0 

在Mysql工作台6.3.4.0中closures安全模式

编辑菜单=>首选项=> SQL编辑器:其他部分:点击“安全更新”…取消选项

在这里input图像说明