Eu tenho a seguinte consulta:
INSERT INTO table (a) VALUES (0)
ON DUPLICATE KEY UPDATE a=1
Quero o ID da inserção ou da atualização. Normalmente, eu executo uma segunda consulta para obter isso, pois acredito que insert_id () retorna apenas o ID 'inserido' e não o ID atualizado.
Existe uma maneira de INSERT / UPDATE e recuperar o ID da linha sem executar duas consultas?
alter table tablename AUTO_INCREMENT = 0;
a consulta acima para evitar grandes lacunas nos valores de seu ID.Respostas:
Verifique esta página: https://web.archive.org/web/20150329004325/https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
Na parte inferior da página eles explicam como você pode tornar LAST_INSERT_ID significativo para atualizações, passando uma expressão para essa função do MySQL.
No exemplo de documentação do MySQL:
fonte
Para ser exato, se esta é a consulta original:
e 'id' é a chave primária de incremento automático do que esta seria a solução de trabalho:
Está tudo aqui: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
fonte
Você pode olhar para REPLACE, que é essencialmente uma exclusão / inserção, se o registro existir. Mas isso alteraria o campo de incremento automático, se presente, o que poderia interromper o relacionamento com outros dados.
fonte
Não sei qual é a sua versão do MySQL, mas com o InnoDB, houve um erro com o autoinc
bug no 5.1.20 e corrigido no 5.1.23 http://bugs.mysql.com/bug.php?id=27405
bug no 5.1.31 e corrigido no 5.1.33 http://bugs.mysql.com/bug.php?id=42714
fonte
Eu encontrei um problema, quando ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID (id) incrementa a chave primária em 1. Portanto, o id da próxima entrada da sessão será incrementado em 2
fonte
Vale a pena notar, e isso pode ser óbvio (mas eu vou dizer assim mesmo para maior clareza aqui), que REPLACE irá explodir a linha correspondente existente antes de inserir seus novos dados. ON DUPLICATE KEY UPDATE atualizará apenas as colunas especificadas e preservará a linha.
Do manual :
fonte
As soluções existentes funcionam se você usar o incremento automático. Eu tenho uma situação em que o usuário pode definir um prefixo e deve reiniciar a sequência em 3000. Devido a esse prefixo variado, não posso usar o incremento automático, o que torna last_insert_id vazio para inserções. Eu o resolvi com o seguinte:
Se o prefixo existir, ele será incrementado e preenchido last_insert_id. Se o prefixo não existir, ele inserirá o prefixo com o valor 3000 e preencherá last_insert_id com 3000.
fonte