Qual è il modo corretto / più veloce per aggiornare / inserire un record in sql (Firebird / MySql)
Domanda
Ho bisogno di un po 'di SQL per aggiornare un record in un database se esiste e inserirlo in caso contrario, guardarsi intorno sembra esserci diverse soluzioni per questo, ma non so quali sono i modi corretti / accettati per fai questo.
Preferirei che funzionasse sia su Firebird 2 che su MySQL 5 poiché l'aggiornamento dovrà essere eseguito su entrambi i database, e sarebbe più semplice se lo stesso SQL fosse eseguito su entrambi, se funzionasse su più database che essere un vantaggio.
Anche la velocità e l'affidabilità tengono conto dell'affidabilità rispetto alla velocità in questo caso, ma verranno potenzialmente utilizzate per aggiornare migliaia di record in rapida successione (su tabelle diverse).
eventuali sottomissioni?
Soluzione
Dovresti usare qualcosa del genere:
BEGIN TRANSACTION
IF EXISTS (SELECT * FROM the_table WHERE pk = 'whatever')
UPDATE the_table SET data = 'stuff' WHERE pk = 'whatever'
ELSE
INSERT INTO the_table (pk, data) VALUES ('whatever', 'stuff')
COMMIT
O questo, ma inviali separatamente e ignora eventuali errori di INSERT sulla violazione dei vincoli della chiave primaria:
INSERT INTO the_table (pk, data) VALUES ('whatever', 'stuff')
UPDATE the_table SET data = 'stuff' WHERE pk = 'whatever'
Altri suggerimenti
In Firebird 2.1 puoi usare AGGIORNA O INSERISCI per casi semplici o MERGE per scenari più complessi.
Per MySQL, prova il comando REPLACE
: http://dev.mysql.com/doc/refman/5.0/en/replace.html
(Vedi il commento su questa risposta di Milan Babuskov per equivalenti su Firebird.)
In firebird prima della 2.1 puoi usare questo modo complicato:
insert into table (id, a, b, c) values (:id, :a, :b, :c)
when SQLCODE -803
do
begin
update table set a = :a, b = :b, c = :c where id = :id;
end;
REPLACE funziona esattamente come INSERT, tranne per il fatto che se una vecchia riga della tabella ha lo stesso valore di una nuova riga per un PRIMARY KEY o un indice UNIQUE, la vecchia riga viene eliminata prima di inserire la nuova riga. >
Sintassi:
SOSTITUIRE [LOW_PRIORITY | RITARDATO] [INTO] tbl_name [(col_name, ...)]
{ VALUES | VALUE}
({expr | DEFAULT},...),(...),...
Considerando che: È meglio evitare SOSTITUIRE quando si lavora con vincoli.
Ho usato INSERT in MySQL per aggiornare le righe con:
INSERT INTO table () VALUES () ON DUPLICATE KEY UPDATE key
Ma non puoi usare una chiave generata automaticamente.