MSSQL UPSERT, INSERT INTO ... ON DUPLICATE KEY UPDATE

Programátor MySQL databází přechází na MSSQL. MSSQL je pro mne naprostá novinka a zároveň zděšením. Zatím jsem zelenáč a tak budu popisovat mnoho rozdílů mezi styly programování na které jsem jako programátor MySQL zvyklý.


Prvně mě zklamala kompletní informační základna okolo MSSQL. MSDN Books Online mně přišlo hodně chaotické, ale dá se v tom zoorientovat, avšak na bohaté praktické ukázky použití nebo rozsáhlé příspěvky můžete zapomenout. Podobně je na tom většina internetových zdrojů i tištěných publikací. Internetových diskusí na toto téma je poskromnu a převážně se jedná o nedořešené problémy nebo odpovědi typu: ,,Proč to dělat tak, když to jde i se základy" (jinak řečeno, diskuse je zabitá a ani po třech letech není problém vyřešen, škoda kliknutí v google). Jakýkoli zájem o nějakou optimalizaci žádný, komunita programátorů okolo MSSQL se pravděpodobně soustředí (a to z pochopitelných důvodů) převážně na komerční úrovni a o své problémy se dělí uvnitř firmy.

Jedním z takových problémů jsou běžné SQL dotazy využívané na MySQL, např. INSERT INTO ... ON DUPLICATE KEY UPDATE, zkracovaný někdy jako UPSERT, v některých publikacích je uváděn jako optimalizační metoda, např. v publikaci MySQL - Oficiální průvodce tvorbou, správou a laděním databází (strana 182), tuto metodu zmiňuji i v článku INSERT INTO ... ON DUPLICATE UPDATE, ale co když nechceme, aby se nový záznam vytvořil, ale jen upravil existující?, související diskuse pod článkem však její platnost popírá a proto byla diskuse rozšířena o článek Jeden dotaz do databáze nebo tisíce? ... je to stejné? Tento článek řeší nejužší místo mezi databází a databázovým layerem, zdá se že MySQLi si dokáže celkem úspěšně poradit s tisíci dotazy i položenými zvlášť, ovšem při připojení přes ODBC řešíme znovu stejný problém.

Při hledání alternativy této metody pro MSSQL jsem našel pouze toto řešení:

  1. IF EXISTS (SELECT * FROM Table1 WHERE Column1='SomeValue')
  2. UPDATE Table1 SET (...) WHERE Column1='SomeValue'
  3. ELSE
  4. INSERT INTO Table1 VALUES (...)

Vhodnější, by mohl být tento přístup:

  1. UPDATE Table1 SET (...) WHERE Column1='SomeValue'
  2. IF @@ROWCOUNT=0 INSERT INTO Table1 VALUES (...)

Co na to říkáte? Ještě to tak napsat jako hromadný insert!