mysql удалить в безопасном режиме


у меня есть инструктор таблица и я хочу удалить записи, которые имеют зарплату в диапазоне Интуитивный способ выглядит так:

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. как переписать этот код, чтобы он работал в безопасном режиме?

спасибо!

4 67

4 ответа:

Googling вокруг, популярный ответ, кажется,"выключить безопасный режим":

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

если честно, я не могу сказать, что у меня когда-либо была привычка работать в безопасном режиме. Тем не менее, я не совсем согласен с этим ответом, так как он просто предполагает, что вы должны изменить конфигурацию своей базы данных каждый раз, когда вы сталкиваетесь с проблемой.

Итак, ваш второй запрос ближе к отметке, но попадает в другую проблему: MySQL применяет несколько ограничений к подзапросам, и один из них заключается в том, что вы не можете изменить таблицу при выборе из нее в подзапросе.

цитирование из руководства MySQL,ограничения на подзапросы:

В общем, вы не можете изменить таблицу и выбрать из той же таблицы в подзапросе. Например, это ограничение применяется к отчетности следующие формы:

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.

этот последний бит-ваш ответ. Выберите целевые идентификаторы во временной таблице, а затем удалите, сославшись на идентификаторы в этой таблице:

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 workbench 6.3.4.0

меню редактирования = > настройки = > редактор SQL: другой раздел: нажмите на кнопку "безопасные обновления"... для отключите опцию

Введите описание изображения здесь

похоже, что в вашем сеансе MySql установлен параметр safe-updates. Это означает, что вы не можете обновить или удалить записи без указания ключа (например. первичный ключ) в предложении where.

попробовать

SET SQL_SAFE_UPDATES = 0;