INSERT INTO ... ON DUPLICATE UPDATE, ale co když nechceme, aby se nový záznam vytvořil, ale jen upravil existující?

Určitě často využíváte funkce ON DUPLICATE UPDATE, já tedy ano. Ušetří to hodně času a dovolí to podle unikátního identifikátoru upravit sadu řádků jedním dotazem.


Například máte sadu záznamů s párovými klíči, v praxi to může být seznam identifikátorů produktů a k tomu ceny v databázi dbf, csv, xml souboru nebo jiným způsob uložené mimo databázi.

Například máme databázi uživatelů a potřebujeme upravit jejich kredit, pomocí tohoto dotazu:

  1. INSERT INTO uzivatele (id_uzivatel, kredit) VALUES (1, 100), (2, 150), (10, 300) ON DUPLICATE KEY UPDATE kredit=VALUES(kredit);

Ovšem může se stát, že nechcete, aby při neexistenci unikátního identifikátoru (id_uzivatel) byl nový uživatel vložen.

Já to řeším dočasnou tabulkou a sadou dotazů, takto:

  1. $q = "CREATE TEMPORARY TABLE `temp_uzivatele` (
  2. `id_uzivatel` INT(11) NOT NULL,
  3. `kredit` INT(11) NOT NULL,
  4. PRIMARY KEY (`id_uzivatel`)
  5. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;";
  6. if (!$sql->query($q)) throw new Exception("Nepodařilo se vytvořit dočasnou tabulku.");
  7.  
  8. $ins=array("(1,100)","(2,150)","(10,300)"); // pochopitelně toto pole je vytvořeno v nějakém cyklu, který prochází csv, dbf, xml nebo jiný typ uložených dat
  9.  
  10. $q="INSERT INTO temp_uzivatele (id_uzivatel, kredit) VALUES ".implode(",", $ins).";";
  11. if (!$sql->query($q)) throw new Exception("Nepodařilo se naplnit dočasnou tabulku.");
  12. $q="UPDATE uzivatele u JOIN temp_uzivatele tu ON (u.id_uzivatel=tu.id_uzivatel) SET u.kredit=tu.kredit;";
  13. if (!$sql->query($q)) throw new Exception("Nepodařilo se upravit data z dočasné tabulky.");

Co vy nato? Nějaký lepší způsob nebo přístup?

podobné články

24.01.2009Jeden dotaz do databáze nebo tisíce? ... je to stejné?(88%)
24.02.2009MSSQL UPSERT, INSERT INTO ... ON DUPLICATE KEY UPDATE(13%)