ON DUPLICATE KEY UPDATE не срабатывает при несовпадающих названиях полей в исходной и целевой таблицах
CREATE TABLE `contacts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`marital_status` tinyint(1) DEFAULT NULL,
PRIMARY KEY (`id`),
)
ENGINE=MyISAM DEFAULT CHARSET=utf8
CREATE TABLE `anketa` (
`id` int(11) NOT NULL DEFAULT '0',
`marital_status_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
)
ENGINE=MyISAM DEFAULT CHARSET=utf8
Почему не работает вставка выбранного значения со следующим кодом:
INSERT INTO `contacts` (`marital_status`)
SELECT `marital_status_id`
FROM `anketa`
WHERE `id`=215409
ON DUPLICATE KEY UPDATE
`marital_status` = VALUES(`marital_status`)
И чем по смыслу отличается такой вариант кода (разница в самой концовке, тоже не срабатывает):
INSERT INTO `contacts` (`marital_status`)
SELECT `marital_status_id`
FROM `anketa`
WHERE `id`=215409
ON DUPLICATE KEY UPDATE
`marital_status` = `marital_status_id`";
Имеющиеся в документации пояснения не помогают. Что я не учёл?
P.S. нашел ошибку - "нечаянно" удалил из запроса уникальное поле (id) - после его возвращения заработало:
INSERT INTO `contacts` (`id`, `marital_status`)
SELECT `id`, `marital_status_id`
FROM `anketa`
WHERE `id`=215409
ON DUPLICATE KEY UPDATE
`id` = VALUES(`id`),
`marital_status` = VALUES(`marital_status`)
Ответы (1 шт):
Почему INSERT INTO `contacts` (`id`, `marital_status`) ... может работать, а INSERT INTO `contacts` (`marital_status`) ... нет?
Предположение только одно. id является NOT NULL полем, у которого не указано DEFAULT значение (в т.ч. автогенерируемое). Это и приводит к ошибке.
Почему INSERT INTO `contacts` (`id`, `marital_status`) ... ON DUPLICATE KEY UPDATE ... может и вставлять, и обновлять, а INSERT INTO `contacts` (`marital_status`) ... ON DUPLICATE KEY UPDATE ... всегда вставляет?
ON DUPLICATE KEY UPDATE интересует только нарушение ограничения уникальности.
Если второй вариант не приводит к ошибке, значит, поле id объявлено как AUTO_INCREMENT, и для него генерируется уникальное значение. Поскольку у ODKU прописано UPDATE `marital_status` = VALUES(`marital_status`), то это поле не уникально. Итого - никакого дублирования в принципе нет, и у ODKU нет оснований для срабатывания и обновления.
чем по смыслу отличается такой вариант кода
В первом варианте `marital_status` = VALUES(`marital_status`) полю при обновлении присваивается то значение, которое было бы в него вставлено, если бы не было ошибки дублирования.
Во втором варианте `marital_status` = `marital_status_id` полю просто присваивается значение из другого поля той же записи.
marital_status_idиmarital_status- поля из разных таблиц – Simply One
В таком случае этот вариант синтаксически некорректен. В ODKU нельзя ссылаться на поля таблицы-источника - они уже недоступны. ODKU - это фактически триггер. Ссылаться можно только на поля обновляемой таблицы - если брать аналогию с триггером, то просто поле есть поле из OLD, а поле-аргумент функции VALUES() - поле из NEW.