这是我会尝试的:
UPDATE relations r
LEFT JOIN relations s
ON r.relation_id = s.id
SET r.relation_id = NULL
WHERE s.id IS NULL
AND r.relation_id IS NOT NULL;
(我不确定这是否可行;这可能会引发异常,因为关系表被引用了两次。)
如果多表更新不起作用,我将创建一个工作表,使用查询(标识要更新的行)填充工作表,然后使用工作表运行多表更新。
此查询将识别具有relation_id
不指向现有 的行id
:
SELECT r.*
FROM relations r
LEFT JOIN relations s
ON r.relation_id = s.id
WHERE s.id IS NULL
AND r.relation_id IS NOT NULL;
您不需要拉所有列,只需要拉主键。(我在这里假设主键是单列id
。)
CREATE TABLE work_table (id int PRIMARY KEY);
INSERT INTO work_table (id)
SELECT r.id
FROM relations r
LEFT JOIN relations s
ON r.relation_id = s.id
WHERE s.id IS NULL
AND r.relation_id IS NOT NULL;
UPDATE relations r
JOIN work_table s
ON r.id = s.id
SET r.relation_id = NULL;
DROP TABLE work_table;
附录:
如果你使用 InnoDB,你可以通过定义外键约束来避免这种类型的数据完整性问题。例如:
ALTER TABLE relations ADD CONSTRAINT relations_FK
FOREIGN KEY (relation_id) REFERENCES relations(id)
ON UPDATE CASCADE ON DELETE SET NULL;
这将禁止对表进行更改,这将导致relation_id
具有与表中存在的值不同的值id
。(这要求它id
是 PRIMARY KEY,并且该 relation_id 具有相同的数据类型。)