#mysql #sql #relational-database
#mysql #sql #реляционная база данных
Вопрос:
У меня есть база данных следующим образом
CREATE TABLE `user_relationships` (
`id` int(11) NOT NULL,
`user_id` int(20) UNSIGNED NOT NULL,
`relationship` varchar(50) NOT NULL,
`institution_id` int(20) UNSIGNED NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
У меня есть следующие данные
--------------------------------------------
id | user_id | relationship | institution_id
--------------------------------------------
1 | 12 |is_working_at | 24
--------------------------------------------
2 | 12 |was_working_at| 23
--------------------------------------------
3 | 12 |was_working_at| 55
--------------------------------------------
4 | 12 |is_trained_at | 55
--------------------------------------------
Теперь у меня есть сценарий, в котором я хочу объединить учреждение 55 (child_id) с учреждением 23 (parent_id). Для этого я выполняю следующий запрос
UPDATE user_relationships
SET institution_id='{$parent_id}'
WHERE (
relationship IN ('was_working_at', 'is_working_at', 'is_trained_at') AND
institution_id = {$child_id}
)
Это работает нормально, за исключением случаев, когда между пользователем и учреждением уже существуют идентичные отношения. В этом случае я получаю сообщение об ошибке типа
SQLSTATE[23000]: нарушение ограничения целостности: 1062 повторяющихся записи ’12-was_working_at-23′ для ключа ‘user_id’
Как я могу это решить? Существует ли эффективный способ написания sql-запроса, который создаст запись только в том случае, если ранее не существовало идентичных отношений?
Ответ №1:
Вы можете ОБНОВИТЬ IGNORE:
UPDATE IGNORE user_relationships
SET institution_id='{$parent_id}'
WHERE
relationship IN ('was_working_at', 'is_working_at', 'is_trained_at') AND
institution_id = {$child_id};
С модификатором IGNORE оператор update не прерывается, даже если во время обновления возникают ошибки. Строки, для которых возникают конфликты с дублированием ключа при уникальном значении ключа, не обновляются. Строки, обновленные до значений, которые могли бы вызвать ошибки преобразования данных, вместо этого обновляются до ближайших допустимых значений.
Но после этого обновления вы должны решить, что должно быть dun с не обновленными строками. Может быть, вам нужно удалить их с помощью:
DELETE FROM user_relationships
WHERE
relationship IN ('was_working_at', 'is_working_at', 'is_trained_at') AND
institution_id = {$child_id};
Комментарии:
1. Огромное спасибо @Slava Rozhnev. Это сработало, как и ожидалось..