J'ai un instructeur de table et je veux supprimer les enregistrements qui ont un salaire dans une fourchette Une manière intuitive est comme ceci:
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).
J'écris donc 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);
cela ne produit pas d'erreur.
Ma question est:
- que signifie vraiment ce message d'erreur et pourquoi mon code est erroné?
- comment réécrire ce code pour le faire fonctionner en mode sans échec?
Merci!
Réponses:
En cherchant sur Google, la réponse la plus populaire semble être "il suffit de 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 déjà pris l'habitude de fonctionner en mode sans échec. Pourtant, je ne suis pas tout à fait à l'aise avec cette réponse car elle suppose simplement que vous devriez changer la configuration de votre base de données 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 restrictions 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, Restrictions sur les sous - requêtes :
Ce dernier élément est votre réponse. Sélectionnez les ID cibles dans une table temporaire, puis supprimez 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 .
la source
ID
, alors que ma réponse utiliseid
.Vous pouvez faire croire à MySQL que vous spécifiez en fait une colonne de clé primaire. Cela vous permet de «remplacer» le mode sans échec.
En supposant que vous ayez une table avec une clé primaire numérique à incrémentation automatique, vous pouvez effectuer les opérations suivantes:
DELETE FROM tbl WHERE id <> 0
la source
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
la source
J'ai une solution beaucoup plus simple, elle fonctionne pour moi; c'est également une solution de contournement, mais peut être utilisable et vous n'avez pas à modifier vos paramètres. Je suppose que vous pouvez utiliser une valeur qui ne sera jamais là, puis vous l'utilisez dans votre clause WHERE
SUPPRIMER DE MaTable O MyField EST_NOT_EQUAL AnyValueNoItemOnMyFieldWillEverHave
Je n'aime pas trop cette solution non plus, c'est pourquoi je suis ici, mais ça marche et ça semble mieux que ce qu'on lui a répondu
la source