MYSQL Обновление нескольких полей из полей другой таблицы - PullRequest
2 голосов
/ 17 июня 2009

Сценарий:

У меня есть приложение, в котором есть таблица конфигурации, в которой хранятся данные конфигурации для каждого веб-сайта, который использует приложение. Я добавил пару дополнительных столбцов в таблицу конфигурации и развернул это для всех приложений. С тех пор я обновил эти новые столбцы данными, которые должны быть одинаковыми во всех таблицах конфигурации.

Как бы я поступил так?

Моей первой мыслью было бы дублировать таблицу и сделать следующее:

UPDATE `config` SET `config`.`new1` = `tmp_config`.`new1`, `config`.`new2` = `tmp_config`.`new2` LEFT JOIN `tmp_config` ON (`tmp_config`.`tmp_id` = `config`.`id`)

Будет ли это иметь желаемый эффект.

Ответы [ 5 ]

8 голосов
/ 17 июня 2009

Для меня сработало следующее (ИСПОЛЬЗОВАНИЕ ВНУТРЕННЕГО соединения и перемещение SET в конец запроса:

UPDATE `config` INNER JOIN `tmp_config` ON (`tmp_config`.`id` = `config`.`id`) 
SET `config`.`new1` = `tmp_config`.`new1`, `config`.`new2` = `tmp_config`.`new2` 

Спасибо за вашу помощь!

3 голосов
/ 17 июня 2009

Я не совсем понимаю все ваши вопросы. Где вы меняли конфиг? Я читаю ваши объяснения как:

  1. Вы изменили схему для всех приложений
  2. Вы обновили конфигурации приложений в других местах

См. Ответ VolkerK о правильном синтаксисе для многостоловых обновлений.

Какой механизм хранения вы используете? Если это InnoDb (или другой механизм, поддерживающий транзакции), вы должны начать транзакцию перед выполнением запроса. Затем вы можете проверить, что результат является желаемым, прежде чем вносить какие-либо изменения:

Пример:

mysql> START TRANSACTION;

mysql> SELECT * FROM Configs LIMIT 5; - Посмотрите, как это выглядит до

mysql> Запустите запрос на обновление здесь

mysql> SELECT * FROM Configs LIMIT 5; - Убедитесь, что результат является ожидаемым

mysql> COMMIT;

2 голосов
/ 17 июня 2009

Это должно привести к обновлению new1 и new2 в конфигурации до значений new1 и new2 в tmp_config, где всегда совпадают идентификаторы из двух таблиц (и ноль, если в tmp_config нет совпадений).

Я полагаю, это то, что вы сказали, что пытаетесь сделать.

Из справки об обновлении MySql :

Вы также можете выполнять операции обновления покрытие нескольких столов. Тем не менее, вы нельзя использовать ORDER BY или LIMIT с ОБНОВЛЕНИЕ нескольких таблиц. Предложение table_references перечисляет таблицы участвуют в объединении. это синтаксис описан в разделе 12.2.8.1, «Синтаксис JOIN». Вот пример:

ОБНОВЛЕНИЕ элементов, месяц SET items.price = month.price ГДЕ items.id = month.id;

В этом случае они не используют только синтаксис «JOIN», но синтаксис JOIN должен быть действительным, вам просто нужно сделать это до предложения SET.

Это будет выглядеть примерно так:

UPDATE `config` 
  LEFT JOIN `tmp_config` ON (`tmp_config`.`tmp_id` = `config`.`id`)
  SET `config`.`new1` = `tmp_config`.`new1`, `config`.`new2` = `tmp_config`.`new2` 
1 голос
/ 17 июня 2009

Синтаксис обновления нескольких таблиц не позволяет JOIN, где вы положили его, см. http://dev.mysql.com/doc/refman/5.0/en/update.html

UPDATE 
  <code>config</code>, <code>tmp_config</code>
SET
  <code>config</code>.<code>new1</code> = <code>tmp_config</code>.<code>new1</code>,
  <code>config</code>.<code>new2</code> = <code>tmp_config</code>.<code>new2</code>
WHERE
  <code>tmp_config</code>.<code>tmp_id</code> = <code>config</code>.<code>id</code>
должен сделать трюк (без проверки, без гарантии; -))
1 голос
/ 17 июня 2009

нужно сделать как:

редактировать

CREATE TABLE newtable SELECT * FROM oldtable;

MySQL creates new columns for all elements in the SELECT. For example: 
mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
    ->        PRIMARY KEY (a), KEY(b))
    ->        TYPE=MyISAM SELECT b,c FROM test2;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...