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)
6 comentários:
Muito simples essa solução. Muito mais simples que o merge inclusive.
Bom post Leo.
[]'s
Achei um pouco alarmista... aliás.. a maioria dos bancos não implementa o SQL 2008 totalmente, exceto talvez pelo próprio DB2, já que a especificação é praticamente baseada nele.
Maioria dos bancos open-source.
DB2 e Oracle que são os dois principais bancos comerciais implementam o MERGE.
A partir dessas peculiaridades (idiossincrasias de implementação) aí fica claro que o código SQL feito para um banco não irá funcionar facilmente em outro, ou seja, a ideia de que o desenvolvimento em camadas garante trocar de banco de dados facilmente é apenas uma falácia. Eu sou a favor do desenvolvimento em camadas sim, mas a decisão do banco de dados a ser utilizado no sistema não é algo fácil de ser trocado no futuro. O mesmo vale para a camada de apresentação (interface com o usuário). Também vale para ilustrar outro cenário. Dizem que software open source é tão bom quanto o proprietário, mas tá aí um exemplo claro que na prática a história é outra. Bom post!
"Dizem que software open source é tão bom quanto o proprietário, mas tá aí um exemplo claro que na prática a história é outra. Bom post!"
Depende de quem desenvolve não? Não se é pago ou free....
Não entendo com faria isso com o merge. O merge atualiza a coluna quando já existe o registro, certo?
Postar um comentário