SQL: podmínka v UPDATE

Každý, kdo pracuje při programování s databázemi, zná příkaz UPDATE a ví, jak se aktualizuje konkrétní řádek/řádky, když si je omezí podmínkami v části WHERE. I měněnou hodnotu lze zapodmínkovat, aby se ušetřil zbytečný dotaz.

Typický příklad, kde se zbytečně používají sekvence několika SQL příkazů, je například přepínání mezi zobrazováním a nezobrazováním položky (uživatele, kategorie, produktu). Velmi často viděný postup je (v pseudojazyce): 

Reklama


aktualni_stav := db.fetch_value("SELECT public FROM tabulka WHERE tabulka_id=" + (int)id);
if(aktualni_stav<>0):
  db.query("UPDATE tabulka SET public=0 WHERE tabulka_id=" + (int)id)
else:
  db.query("UPDATE tabulka SET public=1 WHERE tabulka_id=" + (int)id)

Zkrátka napřed si, prvním dotazem, odchytí aktuální stav a druhým dotazem jej změní, v závislosti na tom, jaký stav měl atribut entity. 2×proběhne zbytečná konverze na dbConnectoru, a stejněkrát bude databáze vyhledávat správný řádek. Sloupec public je číselného typu, podporu BOOLEANu v PostgreSQL považuji spíše za výjimku.

Přitom to jde jediným SQL příkazem:

  • PostgreSQL: UPDATE "tabulka" SET "public" = CASE WHEN "public"=0 THEN 1 ELSE 0 END WHERE "tabulka_id"=číslo;
  • FirebirdSQL:
    • UPDATE tabulka SET public = IIF(public=0, 1, 0 ) WHERE tabulka_id = číslo;
    • UPDATE tabulka SET public = CASE WHEN public=0 THEN 1 ELSE 0 END WHERE tabulka_id=číslo;
  • MySQL/MariaDB:
    • UPDATE `tabulka` SET `public`= IF((`public`=0), 1, 0) WHERE `tabulka_id`= číslo;
    • UPDATE `tabulka` SET `public` = CASE WHEN `public`=0 THEN 1 ELSE 0 END WHERE `tabulka_id`=číslo;
  • SQLite: UPDATE "tabulka" SET "public"=CASE WHEN "public"<>0 THEN 0 ELSE 1 END WHERE "tabulka_id"= číslo;

Ano, jeden zápis je téměř stejný pro všechny databáze, ale proč nevyužít možnost kratšího zápisu u FbSQL, nebo MariaDB/MySQL.

Zabývám se pouze nejrozšířenějšími F/L/OSS SQL databázemi, k proprietárním mám omezený přístup. Bohužel i přes existenci „SQL norem“ (SQL-92 ,SQL:1999, SQL:2003, …) není jazyk stejný, ani nejsou jednotné typy atributů napříč celým spektrem SQL databází.

Komentáře

2 komentáře: „SQL: podmínka v UPDATE“

  1. Ivan avatar
    Ivan

    tento konrkténí případ byse dle mého dal řešit úplně bez podmínky, když vím, že hodnota tam bude vždy 0 nebo 1 ?

    UPDATE `tabulka` SET `public` = 1 – `public` WHERE `tabulka_id`=číslo;

    1. Marek Olšavský avatar

      [Ivan]: Hezké, pro jeden konkrétní případ. Kontrukce CASE může mít podstatně víc větví, než lze popsat takto jednoduše.
      Dávám Vám za pravdu, ale pouze v tomto (nevhodně) zvoleném příkladu. Bohužel až moc často viděném v cizích kódech.

%d bloggers like this: