这是我想尝试:
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具有相同的数据类型。)
您确定可以使用子查询自行更新表吗? – Sebas
MySQL说: #1093 - 您无法在FROM子句中指定目标表'关系'进行更新 – Pepijn
您是通过表单还是myPhpAdmin手动输入relations_id?通常这些都是自动编号,所以你不应该碰它们 –