首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在安全模式下删除mysql

在安全模式下删除mysql
EN

Stack Overflow用户
提问于 2014-02-18 07:25:57
回答 4查看 283.5K关注 0票数 101

我有一个表格讲师,我想删除工资在某个范围内的记录,直观的方法如下:

delete from instructor where salary between 13000 and 15000;

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

因此,我编写了以下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. 如何重写此代码以使其在安全模式下工作?

谢谢!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-02-18 07:50:14

在谷歌上搜索一下,流行的答案似乎是"just turn off safe mode"

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

老实说,我不能说我已经养成了在安全模式下跑步的习惯。尽管如此,我对这个答案并不完全满意,因为它只是假设您应该在每次遇到问题时都去更改数据库配置。

因此,您的第二个查询更接近实际,但是遇到了另一个问题: MySQL对子查询应用了一些限制,其中之一是在子查询中进行选择时不能修改表。

引用自Restrictions on Subqueries的MySQL手册

通常,您不能修改表并从子查询中的同一个表中进行选择。例如,此限制适用于以下形式的语句:

从t的位置删除...(选择...从t ...);更新t ...WHERE col =(选择...FROM t ...);{INSERT|REPLACE} INTO t (SELECT ...从t开始...);

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

更新t ...WHERE col = (SELECT * FROM (SELECT ...从t开始...)作为_t ...);

在这里,from子句中的子查询的结果被存储为一个临时表,因此在对t进行更新时,t中的相关行已经被选中。

最后一点就是你的答案。在临时表中选择目标in,然后通过引用该表中的in将其删除:

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

SQLFiddle demo

票数 255
EN

Stack Overflow用户

发布于 2016-06-10 19:56:21

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

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

DELETE FROM tbl WHERE id <> 0
票数 22
EN

Stack Overflow用户

发布于 2016-04-03 01:11:53

在Mysql workbench 6.3.4.0中关闭安全模式

编辑菜单=>首选项=> SQL编辑器:其他部分:单击“安全更新”...取消选中选项的步骤

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21841353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档