Hoje finalmente me deparei com uma feature cuja solução direta era fazer um MERGE no MySQL.
Para minha surpresa o MySQL não suporte MERGE [1].
Como assim ? Este comando existe desde 2008 no padrão SQL:2008 e ainda não foi implementado.
Enfim, é o custo de não pagar por uma licença.
Pesquisando um pouco descobri outro comando para fazer o trabalho do MERGE.
O ponto negativo é que terei que usar um comando específico do MySQL.
Depois se quiser trocar de banco de dados terei que reescrever todas as queries.
Foda né ? Posteriormente qual o custo disso ?
Não compensa pagar logo a licença de um BD decente ?
Pode ser que o custo de adaptação posterior em termos de desenvolvimento, testes, homologação seja muito mais caro que pagar a licença do Oracle ou DB2.
Enfim, uma coisa para se pensar...
Mas voltando a solução do problema.
A primeira solução com que me deparei foi o REPLACE [3].
Mas lendo a documentação me deparei com a seguinte frase.
REPLACE
works exactly like INSERT
, except that if an old row in the table has the same value as a new row for aPRIMARY KEY
or a UNIQUE
index, the old row is deleted before the new row is inserted.
Porque diabos ele faz um DELETE e depois um INSERT ao invés de fazer um simples UPDATE ?
Alguém pode me explicar isso ?
Isso inviabilizou o uso do REPLACE devido a restrições de chaves estrangeiras que todos conhecem. Não poderia apagar e escrever linhas referenciadas por outras tabelas.
Pesquisando com mais cuidado achei o salvado da pátria que é o
INSERT ... ON DUPLICATE KEY UPDATE [4]
Pois bem, ele resolve exatamente o que queria fazer com o MERGE.
O único problema é que isso é uma extensão do MySQL deixando a query fora do padrão.
Para referência segue um query com o KEY UPDATE
INSERT INTO USERS ( id, name, location)
VALUES
( 1, 'leonardo', 'mantena')
ON DUPLICATE KEY UPDATE
name = VALUES (name),
location = VALUES (location)