Come aggiornare solo alcuni campi in un record MySQL, in base al loro attuale valore: l'utilizzo di CASE WHEN.
In questa pillola di web vediamo un caso particolare di UPDATE di un record in MySQL / MariaDB, nel quale alcuni suoi campi si aggiornano sempre, mentre per altri devono verificarsi certe condizioni, come il non essere ancora valorizzatI oppure l'avere un determinato valore. Queste condizioni non le verifico con il WHERE, ma direttamente nel momento in cui sto facendo l'UPDATE utilizzando il costrutto CASE WHEN.
Per capire di cosa stiamo parlando vediamo subito un esempio pratico.
Abbiamo un sito web, con relativo database ed una tabella contentente i "bot", cioè gli spider che analizzano il contenuto dei siti.
La nostra tabella è così strutturata
CREATE TABLE IF NOT EXISTS `bot` (
`bot_id` smallint(3) unsigned NOT NULL AUTO_INCREMENT,
`bot_nome` varchar(255) DEFAULT NULL,
`bot_count` int(10) unsigned NOT NULL DEFAULT '0',
`bot_first` datetime DEFAULT NULL,
`bot_last` datetime DEFAULT NULL,
PRIMARY KEY (`bot_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Salviamo un po di records:
INSERT INTO `bot` (`bot_id`, `bot_nome`, `bot_count`, `bot_first`, `bot_last`) VALUES
(1, 'AdsBot-Google', 0, NULL, NULL),
(2, 'Teoma', 0, NULL, NULL),
(3, 'alexa', 0, NULL, NULL),
(4, 'froogle', 0, NULL, NULL),
(5, 'Gigabot', 0, NULL, NULL),
(6, 'inktomi', 0, NULL, NULL),
(7, 'looksmart', 0, NULL, NULL);
I records presentano un campo che utilizzerò come contatore di accessi, "bot_count", che di default presenta valore 0, e che incrementeremo di una unità ad ogni accesso del bot nel sito.
Abbiamo poi un campo "bot_first" che verrà valorizzato con la data solo al suo primo accesso.
Infine abbiamo un campo "bot_last" che verrà aggiornato ad ogni accesso, con la data dell'ultimo accesso.
Vediamo come effetturare un UPDATE, su uno qualunque di questi record, all'accesso di un bot.
Se il bot, ad esempio dell'ID 1 (AdsBot-Google), accede al nostro sito opererò così:
UPDATE bot
SET bot_first =
CASE
bot_count
WHEN 0 THEN '2020-03-11 17:17:17'
ELSE bot_first
END,
bot_count=bot_count+1, bot_last='2020-03-11 17:17:17'
WHERE bot_id=1 LIMIT 1
Vediamo come si comporta questo UPDATE.
Sicuramente aggiorniamo sempre sia il contatore "bot_count", a cui aggiungiamo una unità, sia la data di ultimo accesso "bot_last".
Mentre il campo "bot_first" verrà aggiornato SOLO al verificarsi di una condizione precisa, dipendente dal valore di bot_count.
Utilizziamo la funzione condizionale CASE: si apre con CASE e termina con END. Al suo interno indichiamo le condizioni, legate al valore di bot_count
- WHEN 0 THEN '2020-03-11 17:17:17'
Se bot_count vale ancora 0, quindi solo al primo accesso, il campo "bot_first" viene aggiornato con la data - ELSE bot_first
Agli accessi successivi, la condizione bot_count=0 non è più verificata per cui questo campo, e solo questo, non vogliamo che il campo venga aggiornato: va indicato semplicemente il nome del campo "bot_first".
Mediante il costrutto CASE ... WHEN è possibile creare delle istruzioni condizionali complesse prevedendo non solo un'unica condizione, come nel nostro esempio, ma una serie di condizioni alternative.
Di seguito modifichiamo il nostro esempio: non ha molto senso pratico, ma serve a capire come come utilizzare più condizioni: in base a tre possibili valori che può assumere bot_count aggiorno bot_first con una data differente.
UPDATE bot
SET bot_first =
CASE
bot_count
WHEN 0 THEN '2020-03-11 17:17:17'
WHEN 1 THEN '2020-03-12 18:18:18'
WHEN 2 THEN '2020-03-13 19:19:19'
ELSE bot_first
END,
bot_count=bot_count+1, bot_last='2020-03-11 17:17:17'
WHERE bot_id=1 LIMIT 1
Potremmo anche valorizzare il caso ELSE, ad esempio così:
ELSE '2020-03-14 20:20:20'
Potere prendere spunto da questo esempio per applicare la funzione condizionale CASE alle vostre esigenze.