Přesun dat z jedné tabulky do druhé

19.11.2015 (aktualizováno 16.6.2017) Pavel Databáze

Jak jednoduše vložit data z jedné tabulky do jiné a jak zachovat data z tabulky 1 či tabulky 2? Nebo zachovat úplně všechna?

Přesun dat z jedné tabulky do druhé

Proces spojování tabulek se provádí na jednom ze systému 2x ročně. Data se přesunují do archívu, kde se nové data vloží do již existující a plných tabulek. Pro každou tabulku ale volím jinou metodu, ukážeme si, jaké jsou možnosti.

Chceme vložit pouze nové údaje

Tuto metodu, ač asi nebude příliš častá, provádím s tabulkou o uživatelích. Po přesunu do archivu se všem uživatelům smaže heslo, protože do archívu nemají přístup. Proto po novém kopírování chci vložit pouze nové uživatele, nikoli přepsat původní.

INSERT ... ON DUPLICATE UPDATE

Tento zápis pro existující řádky neprovede nic. MySQL odhalí, že do pole dosazujeme stejné pole. A aniž by ho četl, ví, že to k ničemu nepovede a dané řádky ignoruje.

INSERT INTO `table_backup`
SELECT *
FROM `table`
ON DUPLICATE KEY UPDATE `id` = `id`

INSERT IGNORE

Druhá možnost, která se zdá být pochopitelnější, ale není úplně správná. V tomto případě MySQL ignoruje úplně vše, včetně chyb. Pokud tedy tabulky nejsou stejné, nebo vkládáte NULL do pole kam to nelze atd..., MySQL tyto chyby ignoruje, ale nezobrazí žádnou chybu. 

INSERT IGNORE INTO `table_backup`
SELECT *
FROM `table`

Chceme staré údaje přepsat

Asi častější možnost je, že zastaralé údaje budeme chtít aktualizovat. Opět se nabízí více možností.

INSERT ... ON DUPLICATE UPDATE

Využijeme podobně jako dříve tuto konstrukci, nyní ale specifikujeme, jaké údaje budeme upravovat. Výhodou je, že můžeme vybrat, které sloupce chceme upravit. Nevýhoda je, že pokud chceme upravit všechny, musíme je napsat všechny.

INSERT INTO `table_backup`
SELECT *
FROM `table`
ON DUPLICATE KEY UPDATE `col1` = VALUES(`col1`), `col2` = VALUES(`col2`)...

Zde využijeme funkce VALUES která obsahuje data z aktuálního řádku. 

REPLACE

Místo INSERT napíšeme REPLACE a je hotovo. Jednoduché? Ale nepraktické. Tento příkaz totiž prvně řádek vymaže, a poté jej nahradí novým. Toto může být problém s cizími klíči na tabulky.

REPLACE INTO `table_backup`
SELECT *
FROM `table`

Chceme zachovat všechny údaje

Pokud potřebujeme zachovat jak údaje z původní tak nové tabulky, musíme počítat s tím, že již nebudou sedět primární klíče. Pokud nové řádky vložíme s novým ID, relace na tabulku nebudou dávat smysl a ztratíme integritu dat.

Jestli toto nevadí, nabízí se velmi jednoduché řešení. Pokud do pole s ID vložíme NULL a máme zde AUTO INCREMENT, vloží se s dalším prvkem v řadě.

INSERT INTO `table_backup`
SELECT NULL, `col2`, `col3`, `col4`, ...
FROM `table`

Vkládání pomocí VALUES

Ukázky počítají s tím, že se hodnoty vkládají z jiné tabulky. Stejný postup ale lze použít i v případě, kdy se vkládají hodnoty přímo pomocí SQL dotazu s klauzulí VALUES.

Následující příkaz tedy také funguje a provede přesně to, co se od něj očekává. Pokude záznam s ID již existuje, v tabulce se změní pouze jméno a příjmení. Pokud ID neexistuje, vloží se. VALUES v klauzuli ON DUPLICATE KEY UPDATE je opět referencí na aktuální zpracovávaný řádek.

INSERT INTO `table_backup`(`id`, `name`, `surname`, `created`) VALUES
(123, 'Pavel', 'Kutac', '2010-01-03'),
(456, 'Franta', 'Novak', '2014-11-17'),
(789, 'Lenka', 'Strelenka', '2012-09-28')
ON DUPLICATE KEY UPDATE `name` = VALUES(`name`), `surname` = VALUES(`surname`);

Máte jiné řešení nebo také používáte tyto metody? Podělte se s námi v komentářích

Přidat komentář

Právě odpovídáte na existující komentář. Zrušit

Komentáře

Novinky z blogu

Přidání balíčku do Composeru bez Packagist

Composer umožňuje přidat balíček, který není zveřejněn na Packagist. Stačí, aby byl ve veřejném či privátním git repozitáři, dostupný lokálně na serveru v jiné složce nebo...

Další články