0

我有一个问题,有时由于人为错误,relation_id 会出现在关系的数据库中,并且没有真正的 id。

SELECT relation_id
FROM relations
WHERE relation_id NOT 
IN (
    SELECT id
    FROM relations
)

这将返回发生这种情况的字段,我想将relation_id 的值切换为NULL。

这是我到目前为止所得到的:

UPDATE `relations` SET relation_id = NULL WHERE relation_id NOT IN (SELECT id FROM relations)

这当然适用于任何其他表,但不适用于关系。有人知道解决方法吗?我确定有办法

4

3 回答 3

3

好吧,错误的原因实际上在错误消息本身中得到了很好的描述……您不能在内部 SELECT 中指定您更新的表。但谁说我们不能更深入?

UPDATE relations 
   SET relation_id = NULL 
 WHERE relation_id NOT IN (
       SELECT id FROM (SELECT id FROM relations) AS take_that_sql
);

这是一个可以使用的SQLFiddle。)

于 2012-06-21T15:24:10.000 回答
1

这是我会尝试的:

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 具有相同的数据类型。)

于 2012-06-21T15:21:10.550 回答
0

试试这个 ::

SELECT r1.relation_id
FROM relations r1
left join relations r2 on (r1.relation_id=r2.id)
where r2.id is null
于 2012-06-21T15:07:52.587 回答