125 messaggi dal 22 agosto 2001
Ciao a tutti,

sto cercando di mettere in una query una situazione che ricorre spesso nella raccolta di dati di traffico o statistiche cronologiche.
In particolare una query che crei o aggiorni un record a seconda se nella tabella, alla data di oggi, è presente o no il record.

Scrivendola si può definire così:

Tabella:

ID
campo1
campo2
...
contatore
data

Query:

"Cerco se esiste un record con campo1 = 'valore1' e data = oggi . Se non esiste lo creo inserendo valori nei rispettivi campi (campo1 = valore1, campo2 = valore2, ecc... , contatore = 1, data = oggi)

Altrimenti, se esiste, aggiorno quel record con contatore = contatore + 1


E' possibile mettere tutto questo in una query per MySQL oppure devo per forza creare uno script che presenti le condizioni per un INSERT o un UPDATE?

Avevo pensato di usare ON DUPLICATE KEY ma in realtà la chiave univoca (ID) non mi dice nulla, è un semplice numero. La mia condizione univoca sarebbe la coppia campo1 e data.


grazie

ciao!
11.886 messaggi dal 09 febbraio 2002
Contributi
ciao,
Mysql dispone del comando REPLACE INTO che si comporta, a seconda che il record esista o no, come una UPDATE e come una INSERT.
Sfortunatamente non credo che si possa usare nel tuo caso perché, se il record esiste, i valori dei suoi campi non vengono trasportati al nuovo record. Il problema si presenterebbe qui:

contatore = contatore + 1
Il vecchio valore di contatore verrebbe semplicemente perso, e l'incremento non sarebbe possibile.

Vediamo se si riesce a risolvere in altro modo, senza evitare troppi round-trips al database. Anzi, cerchiamo di farlo in uno solo.

Per prima cosa aggiungi un indice UNIQUE che coinvolga le due colonne campo1 e campo2. Questo è consigliato a prescindere, perché la tabella non deve ammettere duplicati per la coppia di valoridi campo1 e campo2.
ALTER TABLE `tabella` ADD UNIQUE INDEX `nome_indice` (`campo1`, `campo2`);

A questo punto invia una INSERT E una UPDATE con lo stesso comando.

var cmd = conn.CreateCommand();
cmd.CommandText = "INSERT IGNORE INTO tabella (campo1, campo2, contatore) VALUES (@campo1, @campo2, 0); UPDATE tabella SET contatore=contatore+1 WHERE campo1=@campo1 AND campo2=@campo2";
cmd.Parameters.AddWithValue("@campo1", valoreCampo1);
cmd.Parameters.AddWithValue("@campo1", valoreCampo2);
cmd.ExecuteNonQuery();

Si spiega così:
  • La INSERT IGNORE proverà sempre e comunque ad inserire il record ma, se la coppia di valori campo1,campo2 dovesse già esistere, l'inserimento ovviamente non potrebbe avvenire perché violerebbe il vincolo UNIQUE creato prima. Il comando, tuttavia, NON produrrà un errore per via della clausola IGNORE.
  • Subito verrà eseguita anche l'UPDATE, che avrà sempre successo perché l'eventuale record mancante era stato inserito poco prima dalla INSERT.


ciao
Modificato da BrightSoul il 20 marzo 2013 20.13 -

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.