mysql supprimer en mode sans échec

J’ai un instructeur de table et je veux supprimer les enregistrements qui ont un salaire dans une plage de manière intuitive:

delete from instructor where salary between 13000 and 15000; 

Cependant, en mode sans échec, je ne peux pas supprimer un enregistrement sans fournir une clé primaire (ID).

Donc j’écris le sql suivant:

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

Cependant, il y a une erreur:

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

Je suis confus parce que quand j’écris

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

il ne produit pas d’erreur.

Ma question est:

  1. Que signifie ce message d’erreur et pourquoi mon code est erroné?
  2. Comment réécrire ce code pour le faire fonctionner en mode sans échec?

Merci!

Googler autour, la réponse populaire semble être “juste désactiver le mode sans échec” :

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

Si je suis honnête, je ne peux pas dire que j’ai pris l’habitude de courir en mode sans échec. Cependant, je ne suis pas tout à fait à l’aise avec cette réponse car cela suppose simplement que vous deviez changer la configuration de votre firebase database chaque fois que vous rencontrez un problème.

Ainsi, votre deuxième requête est plus proche de la marque, mais rencontre un autre problème: MySQL applique quelques ressortingctions aux sous-requêtes, et l’une d’elles est que vous ne pouvez pas modifier une table en la sélectionnant dans une sous-requête.

Citant le manuel MySQL, Ressortingctions sur les sous – requêtes :

En général, vous ne pouvez pas modifier une table et la sélectionner dans la même table dans une sous-requête. Par exemple, cette limitation s’applique aux déclarations des formulaires suivants:

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

Exception: L’interdiction précédente ne s’applique pas si vous utilisez une sous-requête pour la table modifiée dans la clause FROM. Exemple:

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

Ici, le résultat de la sous-requête de la clause FROM est stocké en tant que table temporaire, de sorte que les lignes pertinentes dans t ont déjà été sélectionnées au moment où la mise à jour a lieu.

Ce dernier bit est votre réponse. Sélectionnez les ID cibles dans une table temporaire, puis supprimez-les en référençant les ID de cette table:

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

Démo SQLFiddle .

Vous pouvez inciter MySQL à penser que vous spécifiez réellement une colonne de clé primaire. Cela vous permet de “remplacer” le mode sans échec.

En supposant que vous avez une table avec une clé primaire numérique auto-incrémentée, vous pouvez effectuer les opérations suivantes:

 DELETE FROM tbl WHERE id <> 0 

Désactiver le mode sans échec dans Mysql Workbench 6.3.4.0

Menu Edition => Préférences => Editeur SQL: Autre section: cliquez sur “Mises à jour sécurisées” … pour décocher l’option

entrer la description de l’image ici

Il semble que votre session MySQL dispose de l’option de sécurité des mises à jour. Cela signifie que vous ne pouvez pas mettre à jour ou supprimer des enregistrements sans spécifier une clé (ex. Clé primaire) dans la clause where.

Essayer

SET SQL_SAFE_UPDATES = 0;