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):
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 BOOLEAN
u 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“
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;
[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.