2016-06-03 1 views
-2

У меня есть две базы данных, dev и production. Оба они имеют одинаковые таблицы и структуру столбцов.MySQL: Скопируйте определенные столбцы из одной базы данных в другую, сохраняя первичный ключ одинаковым.

Мне нужно переместить некоторые производственные данные в dev, сохранив одинаковые идентификаторы первичного ключа, но с предложением WHERE.

UPDATE 
     dev.tableA, 
     prod.tableA 
    SET 
     dev.tableA.title = prod.tableA.title, 
     dev.tableA.url_title = prod.tableA.url_title, 
     dev.tableA.status = prod.tableA.status, 
     dev.tableA.edit_date = prod.tableA.edit_date 
    WHERE 
     dev.tableA.entry_id = prod.tableA.entry_id 
     AND prod.tableA.channel_id = 7 

Когда я запускаю вышеуказанный запрос, я получаю сообщение, связанное с строкой 0 строк.

Я также пробовал эту инструкцию, но снова с 0 строк.

 UPDATE 
      dev.tableA dt 
      INNER JOIN 
       prod.tableA tt 
     ON 
      tt.entry_id = dt.entry_id 
      SET 
       dt.title = tt.title, 
       dt.url_title = tt.url_title, 
      dt.status = tt.status, 
      dt.edit_date = tt.edit_date 
      WHERE 
      tt.channel_id = 7; 
+0

Значит, есть данные с теми же 'entry_id' в базе данных dev, поскольку вы используете обновление и не вставляете? –

+0

Это правильно. Но мне также нужно вставить несколько новых строк, которые были созданы в процессе производства, но я полагал, что это будет отдельный оператор INSERT, если не будет возможности обрабатывать оба одновременно. – KoalaKid

+0

Скорее всего, вы можете сделать это с помощью 'INSERT IGNORE'. В качестве альтернативы, почему бы не запустить DELETE с этим WHERE в базе данных dev, за которым следует прямой INSERT? – LSerni

ответ

0

Ваши обновления выглядят нормально, но возвращают 0, если значения уже были одинаковыми; По умолчанию MySQL указывает, что строки фактически изменены.

Хотя я бы с отступом больше, как это:

UPDATE dev.tableA AS dt 
    INNER JOIN prod.tableA AS tt 
     ON tt.entry_id = dt.entry_id 
SET dt.title = tt.title 
    , dt.url_title = tt.url_title 
    , dt.status = tt.status 
    , dt.edit_date = tt.edit_date 
WHERE tt.channel_id = 7 
; 

Я вообще избежать INSERT IGNORE и REPLACE INTO запросов; Я видел, как они вызывают больше проблем, чем они того стоят. Вместо того, чтобы ...

INSERT INTO tableA (id, field1, field2, field3) 
SELECT id, field1, field2, field3 
FROM tableB AS b 
WHERE tableB.id NOT IN (SELECT id FROM tableA) 
; 
-- OR (the below version may be faster) -- 
INSERT INTO tableA (id, field1, field2, field3) 
SELECT b.id, b.field1, b.field2, b.field3 
FROM tableB AS b 
LEFT JOIN tableA AS a ON b.id = a.id 
WHERE a.id IS NULL -- assuming id is not nullable 
; 

и точно так же ...

DELETE FROM tableA 
WHERE tableA.field1 NOT IN (SELECT field1 FROM tableB) 
; 
-- OR (the below version may be faster) -- 
DELETE a 
FROM tableA AS a LEFT JOIN tableB AS b ON a.id = b.id 
WHERE b.id IS NULL 
; 
+0

Спасибо, я попробую. – KoalaKid

+0

@KoalaKid Я только что немного их отредактировал, поэтому не забудьте обновиться. – Uueerdo

+0

Предполагаю, что я могу запускать эти запросы по двум базам данных, просто добавляя имя БД перед именем таблицы, например. db_name.table_name? – KoalaKid

0

Вы можете использовать INSERT с ON DUPLICATE KEY UPDATE пункта.

INSERT INTO dev.tableA (entry_id, title, url_title, status, edit_date) 
SELECT entry_id, title, url_title, status, edit_date 
FROM prod.tableA 
WHERE channel_id = 7 
ON DUPLICATE KEY UPDATE 
    title = VALUES(title), url_title = VALUES(url_title), 
    status = VALUES(status), edit_date = VALUES(edit_date) 
+0

спасибо за это. Так что это вставить новые значения, а затем обновить существующие записи, которые имеют разные данные? – KoalaKid

+0

И я также должен запустить это на двух других таблицах, которые все используют один и тот же entry_id как первичный или внешний ключ. Есть ли способ запустить это против всех 3 одновременно? – KoalaKid

+0

q1: Да, это то, что он делает. q2: Вы можете вставлять только одну таблицу за раз. – Barmar

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