2014-02-17 3 views
58

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

Спасибо!

+0

вы хотите сохранить безопасный режим на? и вы используете mySql workbench? – wribit

+0

Ответ на оба вопроса: да. И я удивлен, что, когда я использовал jdbc для удаления записей в базах mysql без ПК, он не вызывает ошибку. Таким образом, безопасный режим предназначен только для workbench mysql? –

+1

no - Я спрашивал, потому что если вы хотите отключить его в workbench mySQL, я мог бы рассказать вам, как это сделать. Лично я работаю с этим ... иметь идентификаторы - это большая безопасность - но развитие мудрое, я нашел, что это боль – wribit

ответ

155

погуглить вокруг, популярный ответ, кажется "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 применяет несколько ограничений для подзапросов, и один из них заключается в том, что вы не можете изменять таблицу при выборе из нее в подзапросе.

Цитируя из руководства 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 instructor WHERE id IN (
    SELECT temp.id FROM (
    SELECT id FROM instructor WHERE salary BETWEEN 13000 AND 15000 
) AS temp 
); 

SQLFiddle demo.

+4

Спасибо за объяснение! Однако я попробовал свой код в workbench mysql, и он все еще сказал: «Вы используете безопасный режим обновления, и вы пытались обновить таблицу без WHERE, которая использует столбец KEY». –

+0

Это неожиданно. Является ли ваш первичный ключ под другим именем? Я замечаю, что ваш вопрос, похоже, указывает, что он называется 'ID', в то время как мой ответ использует' id'. – rutter

+0

Да, я меняю его на ID, и он не работает. Я попробовал удалить из инструктора, где ID = '1', и он работает так, что идентификатор является основным ключом –

6

Выключение безопасного режима в Mysql верстаке 6.3.4.0

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

enter image description here

+2

"как переписать этот код, чтобы он работал ** в безопасном режиме **?" ==> В вашем ответе рассказывается, как отключить безопасный режим;) – ByteHamster

+2

Извините, я полностью не понял этот вопрос. Я нашел эту тему, когда мне не удалось удалить из таблиц с помощью Mysql workbench, и в комментарии с mysql workbench был аналогичный вопрос, но я не могу создавать комментарии. Я подумал, что было бы неплохо написать это здесь для дальнейшего использования ... –

9

Вы можете обмануть MySQL, думая, что на самом деле указана колонка первичного ключа. Это позволяет вам «переопределить» безопасный режим.

Предполагая, что у вас есть таблица с числовым первичным ключом автоинкрементным, вы можете сделать следующее:

DELETE FROM tbl WHERE id <> 0 
0

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

Попробуйте

SET SQL_SAFE_UPDATES = 0;

Смежные вопросы