2012-06-21 2 views
0

У меня проблема, иногда из-за человеческой ошибки в базе данных, отношений и в ней нет реального id.MySQL - выберите, а не вопрос

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) 

Это от курса работает для любой другой таблицы, но только не для отношений. Кто-нибудь знает обход? Я уверен, что есть способ

+0

Вы уверены, что можете удалять таблицу, используя подзапрос себе? – Sebas

+0

MySQL сказал: # 1093 - Вы не можете указать ссылки на целевую таблицу для обновления в предложении FROM. – Pepijn

+0

. Вы вручную вводите отношения_и_ через форму или myPhpAdmin?обычно это автоматические номера, поэтому вы не должны их касаться. –

ответ

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, чтобы поиграть.)

+0

РАБОТЫ! Огромное спасибо :) – Pepijn

0

Попробуйте ::

SELECT r1.relation_id 
FROM relations r1 
left join relations r2 on (r1.relation_id=r2.id) 
where r2.id is null 
+0

Все еще получите ошибку MySQL # 1093. – Pepijn

+0

. Вы можете создать временную таблицу, а затем присоединиться и сделать это ... Поскольку это ограничение mysql, оно не позволит вам обновлять. –

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 был ПЕРВИЧНЫМ КЛЮЧОМ, и этот тип отношения имеет идентичный тип данных.)

Смежные вопросы