Tenho um instrutor de mesa e quero deletar os registros que têm salário em uma faixa. Uma forma intuitiva é assim:
delete from instructor where salary between 13000 and 15000;
No entanto, no modo de segurança, não posso excluir um registro sem fornecer uma chave primária (ID).
Então, escrevo o seguinte sql:
delete from instructor where ID in (select ID from instructor where salary between 13000 and 15000);
No entanto, há um erro:
You can't specify target table 'instructor' for update in FROM clause
Estou confuso porque quando escrevo
select * from instructor where ID in (select ID from instructor where salary between 13000 and 15000);
não produz um erro.
Minha pergunta é:
- o que essa mensagem de erro realmente significa e por que meu código está errado?
- como reescrever este código para fazê-lo funcionar no modo de segurança?
Obrigado!
Respostas:
Pesquisando, a resposta popular parece ser "apenas desligue o modo de segurança" :
SET SQL_SAFE_UPDATES = 0; DELETE FROM instructor WHERE salary BETWEEN 13000 AND 15000; SET SQL_SAFE_UPDATES = 1;
Para ser sincero, não posso dizer que criei o hábito de correr no modo de segurança. Ainda assim, não estou totalmente confortável com essa resposta, pois ela apenas pressupõe que você deve alterar a configuração do banco de dados toda vez que tiver um problema.
Portanto, sua segunda consulta está mais perto do alvo, mas acerta outro problema: o MySQL aplica algumas restrições às subconsultas e uma delas é que você não pode modificar uma tabela enquanto seleciona dela em uma subconsulta.
Citando o manual do MySQL, Restrições em subconsultas :
Essa última parte é a sua resposta. Selecione os IDs de destino em uma tabela temporária e exclua fazendo referência aos IDs nessa tabela:
DELETE FROM instructor WHERE id IN ( SELECT temp.id FROM ( SELECT id FROM instructor WHERE salary BETWEEN 13000 AND 15000 ) AS temp );
Demonstração do SQLFiddle .
fonte
ID
, enquanto minha resposta usaid
.Você pode levar o MySQL a pensar que está realmente especificando uma coluna de chave primária. Isso permite que você "substitua" o modo de segurança.
Supondo que você tenha uma tabela com uma chave primária numérica de incremento automático, você pode fazer o seguinte:
DELETE FROM tbl WHERE id <> 0
fonte
Desligando o modo de segurança no Mysql workbench 6.3.4.0
Menu Editar => Preferências => Editor SQL: Outra seção: clique em "Atualizações seguras" ... para desmarcar a opção
fonte
Tenho uma solução muito mais simples, está funcionando para mim; também é uma solução alternativa, mas pode ser utilizável e você não precisa alterar suas configurações. Presumo que você possa usar um valor que nunca estará lá, então você o usa em sua cláusula WHERE
DELETE FROM MyTable WHERE MyField IS_NOT_EQUAL AnyValueNoItemOnMyFieldWillEverHave
Também não gosto muito dessa solução, por isso estou aqui, mas funciona e parece melhor do que foi respondido
fonte