MySQL пытается удалить все строки, которые не ограничены внешним ключом - PullRequest
4 голосов
/ 02 июля 2010

Хорошо, это (вероятно) очень простой вопрос, но я боюсь, что почти не знаю MySQL, поэтому, пожалуйста, смиритесь со мной.Я просто пытаюсь удалить каждую строку из одной таблицы, которая не ограничена внешним ключом в другой таблице - конкретной таблице, здесь задействованы только две таблицы.Операторы create выглядят примерно так:

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;

Любой мой оператор SQL выглядит так:

DELETE FROM job USING job INNER JOIN jobAssignment WHERE job.Job_Id != jobAssignment.JobId;

Я подумал, что это правильно - он должен удалять все задания из таблицы заданий, для которых естьне существует задания, в котором это задание является внешним ключом.Однако это происходит со следующей ошибкой, когда я пытаюсь ее выполнить:

Невозможно удалить или обновить родительскую строку: ограничение внешнего ключа не выполняется (testdatabase. jobassignment, CONSTRAINT FK_jobassignment_1ИНОСТРАННЫЙ КЛЮЧ (JobId) ССЫЛКИ job (Job_Id))

Так что за глупость я делаю неправильно?

РЕДАКТИРОВАТЬ: Как обычно, я нашел ответтолько через несколько секунд после публикации здесь.Я использовал (совершенно другой) запрос:

DELETE FROM job WHERE Job_Id NOT IN (SELECT JobId FROM jobassignment) 

Из любопытства, это лучший способ сделать это?Была ли моя оригинальная идея осуществимой?И если так, что с ним не так?

Ответы [ 3 ]

7 голосов
/ 02 июля 2010
DELETE FROM job USING job 
LEFT JOIN jobAssignment ON(job.Job_Id = jobAssignment.JobId)
WHERE jobAssignment.JobId IS NULL;
5 голосов
/ 02 июля 2010

Вам, вероятно, понадобится подзапрос, не уверенный, будет ли это работать в mySQL, но что-то похожее, по крайней мере:

DELETE FROM job
WHERE job.Job_Id NOT IN (
  SELECT JobId FROM jobAssignment
)
1 голос
/ 02 июля 2010

Naktibalda предполагает, что подзапрос может быть неэффективным; если это так, вы можете попробовать

DELETE FROM job
     WHERE NOT EXISTS (SELECT *
                           FROM jobassignment
                           WHERE job.Job_Id = jobassignment.Job_Id);

У меня был плохой опыт с IN и NOT IN в прошлом; меньше проблем с НЕ СУЩЕСТВУЕТ.

...