O que é a maneira correta / mais rápido para atualizar / inserir um registro em SQL (Firebird / MySql)
Pergunta
Eu preciso de algum SQL para atualizar um registro em um banco de dados se ele existe e inseri-lo quando ele não, olhando em torno de lá parece ser várias soluções para isso, mas eu não sei quais são as / aceite maneiras corretas para fazer isso.
Eu realmente gostaria que o trabalho em ambos Firebird 2 e MySQL 5 como a atualização terá de ser correu contra os dois bancos de dados, e seria mais simples se o mesmo ran SQL em ambos, se ele trabalhou em mais banco de dados que faria ser um plus.
velocidade e confiabilidade também factor de, confiabilidade sobre a velocidade neste caso, mas ela é potencialmente ser usado para atualizar 1000 de registros em rápida sucessão (ao longo de diferentes tabelas).
quaisquer sujeições?
Solução
Você deve usar algo como isto:
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
Ou isso, mas enviá-los separadamente e ignorar quaisquer erros a partir da inserção cerca de violar as restrições de chave primária:
INSERT INTO the_table (pk, data) VALUES ('whatever', 'stuff')
UPDATE the_table SET data = 'stuff' WHERE pk = 'whatever'
Outras dicas
Em Firebird 2.1 você pode usar atualização ou inserção para casos simples ou MERGE para cenários mais complexos.
Para o MySQL, tente o comando REPLACE
: http: // dev .mysql.com / doc / refman / 5.0 / en / replace.html
(Por favor, veja o comentário sobre esta resposta por Milan Babuskov para equivalentes em Firebird.)
No Firebird antes de 2.1 você pode usar este caminho complicado:
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 funciona exatamente como INSERT, exceto que se um velho linha na tabela tem o mesmo valor que uma nova linha para uma chave primária ou um índice exclusivo, a velha linha é excluída antes da nova linha é inserida.
Sintaxe:
Substitua [LOW_PRIORITY | DELAYED] [EM] nome_tabela [(col_name, ...)]
{ VALUES | VALUE}
({expr | DEFAULT},...),(...),...
Considerando o seguinte:. É melhor evitar REPLACE quando se trabalha com restrições
Eu usei INSERT no MySQL para atualizar linhas com:
INSERT INTO table () VALUES () ON DUPLICATE KEY UPDATE key
Mas você não pode usar um auto gerado chave.