Bon, c'est (probablement) un très question simple, mais je crains de ne connaître presque pas MySQL, alors s'il vous plaît mettre en place avec moi. J'essaye juste de supprimer chaque rangée d'une table qui n'est pas contrainte par une clé étrangère dans une autre table - une table spécifique, il y a seulement deux tables impliquées ici. Les instructions create ressemblent un peu:MySQL tentant de supprimer toutes les lignes qui ne sont pas contraints par la clé étrangère
CREATE TABLE `testschema`.`job` (
`Job_Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`Comment` varchar(255) DEFAULT NULL,
PRIMARY KEY (`Job_Id`) USING BTREE,
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `ermieimporttest`.`jobassignment` (
`JobAssignment_Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`JobId` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`JobAssignment_Id`),
KEY `FK_jobassignment_1` (`JobId`),
CONSTRAINT `FK_jobassignment_1` FOREIGN KEY (`JobId`) REFERENCES `job` (`Job_Id`),
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Toute ma déclaration SQL est:
DELETE FROM job USING job INNER JOIN jobAssignment WHERE job.Job_Id != jobAssignment.JobId;
Je pensais que cela était exact - il devrait supprimer tous les emplois de la table de travail pour lequel il n'existe pas l'affectation de travail qui a ce travail comme c'est la clé étrangère. Cependant, cela ne fonctionne pas avec l'erreur suivante quand je tente de l'exécuter:
Impossible de supprimer ou mettre à jour une ligne de parent. une contrainte de clé étrangère échoue (
testdatabase
jobassignment
, CONTRAINTEFK_jobassignment_1
FOREIGN KEY (JobId
) RÉFÉRENCESjob
(Job_Id
))
Alors quelle chose stupide que je fais mal?
EDIT: Comme d'habitude, j'ai trouvé une réponse seulement quelques secondes après avoir posté ici. J'ai utilisé la requête (complètement différente):
DELETE FROM job WHERE Job_Id NOT IN (SELECT JobId FROM jobassignment)
Par curiosité, est-ce la meilleure façon de le faire? Mon idée originale était-elle réalisable? Et si oui, qu'est-ce qui n'allait pas?
Dans votre instruction, la sous-requête dependend est exécutée pour chaque ligne d'une table de travail, donc c'est très inefficace. – Naktibalda
Votre instruction 'DELETE' affichée semble un peu confuse, mais pour répondre à votre curiosité: pour chaque ligne dans' job', votre 'JOIN' produit une liste de lignes pour chaque ligne dans' jobassignment' qui a un identifiant pas égal à l'ID du travail. Pour le voir plus clairement, transformez votre instruction 'DELETE' en une instruction SELECT. Quelque chose comme ceci: 'SELECT * FROM travail INNER JOIN jobassignment ON travail.Job_Id! = Jobassignment.JobId;' – Mike
Merci Mike. Je vois ce que vous voulez dire maintenant - ma déclaration comme il a été créé un produit croisé des deux tables, moins les lignes où Job_Id == JobId. Essayer de supprimer ceci échoue bien sûr, car il inclut des Jobs qui sont contraints. À votre santé. – Stephen