mysql 在安全模式下删除

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21841353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 20:04:39  来源:igfitidea点击:

mysql delete under safe mode

mysqlsql

提问by roland luo

I have a table instructor and I want to delete the records that have salary in a range An intuitive way is like this:

我有一个表导师,我想删除一个范围内有薪水的记录 一个直观的方法是这样的:

delete from instructor where salary between 13000 and 15000;

However, under safe mode, I cannot delete a record without providing a primary key(ID).

但是,在安全模式下,我无法在不提供主键(ID)的情况下删除记录。

So I write the following sql:

所以我写了下面的sql:

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

However, there is an error:

但是,有一个错误:

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

I am confused because when I write

我很困惑,因为当我写

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

it does not produce an error.

它不会产生错误。

My question is:

我的问题是:

  1. what does this error message really mean and why my code is wrong?
  2. how to rewrite this code to make it work under safe mode?
  1. 此错误消息的真正含义是什么,为什么我的代码是错误的?
  2. 如何重写此代码以使其在安全模式下工作?

Thanks!

谢谢!

回答by rutter

Googling around, the popular answer seems to be "just turn off safe mode":

谷歌搜索,流行的答案似乎是“关闭安全模式”

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

If I'm honest, I can't say I've ever made a habit of running in safe mode. Still, I'm not entirely comfortable with this answer since it just assumes you should go change your database config every time you run into a problem.

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

So, your second query is closer to the mark, but hits another problem: MySQL applies a few restrictions to subqueries, and one of them is that you can't modify a table while selecting from it in a subquery.

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

Quoting from the MySQL manual, Restrictions on Subqueries:

引用 MySQL 手册中的Restrictions on Subqueries

In general, you cannot modify a table and select from the same table in a subquery. For example, this limitation applies to statements of the following forms:

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

Exception: The preceding prohibition does not apply if you are using a subquery for the modified table in the FROM clause. Example:

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

Here the result from the subquery in the FROM clause is stored as a temporary table, so the relevant rows in t have already been selected by the time the update to t takes place.

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

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 中的相关行。

That last bit is your answer. Select target IDs in a temporary table, then delete by referencing the IDs in that table:

最后一点就是你的答案。在临时表中选择目标 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 demo.

SQLFiddle 演示

回答by Hugo Zink

You can trick MySQL into thinking you are actually specifying a primary key column. This allows you to "override" safe mode.

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

Assuming you have a table with an auto-incrementing numeric primary key, you could do the following:

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

DELETE FROM tbl WHERE id <> 0

回答by Peter B

Turning off safe mode in Mysql workbench 6.3.4.0

在 Mysql Workbench 6.3.4.0 中关闭安全模式

Edit menu => Preferences => SQL Editor : Other section: click on "Safe updates" ... to uncheck option

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

enter image description here

在此处输入图片说明

回答by Joaq

I have a far more simple solution, it is working for me; it is also a workaround but might be usable and you dont have to change your settings. I assume you can use value that will never be there, then you use it on your WHERE clause

我有一个更简单的解决方案,它对我有用;这也是一种解决方法,但可能可用,您不必更改设置。我假设你可以使用永远不会存在的值,然后你在你的 WHERE 子句中使用它

DELETE FROM MyTable WHERE MyField IS_NOT_EQUAL AnyValueNoItemOnMyFieldWillEverHave

从 MyTable 中删除 MyField IS_NOT_EQUAL AnyValueNoItemOnMyFieldWillEverHave

I don't like that solution either too much, that's why I am here, but it works and it seems better than what it has been answered

我也不太喜欢那个解决方案,这就是我在这里的原因,但它有效,而且似乎比已经回答的要好