Quando faço uma única linha INSERT
em uma tabela que possui uma AUTO_INCREMENT
coluna, gostaria de usar a LAST_INSERT_ID()
função para retornar o novo AUTO_INCREMENT
valor armazenado para essa linha.
Como muitos desenvolvedores e administradores do Microsoft SQL Server, sem dúvida, sabem que a funcionalidade equivalente no SQL Server ( SCOPE_IDENTITY
e @@IDENTITY
) não ficou isenta de problemas .
Eu sei o estado dos documentos do MySQL:
O ID que foi gerado é mantido no servidor por conexão . Isso significa que o valor retornado pela função para um determinado cliente é o primeiro
AUTO_INCREMENT
valor gerado para a instrução mais recente que afeta umaAUTO_INCREMENT
coluna por esse cliente . Este valor não pode ser afetado por outros clientes, mesmo que eles geremAUTO_INCREMENT
valores próprios. Esse comportamento garante que cada cliente possa recuperar seu próprio ID sem se preocupar com a atividade de outros clientes e sem a necessidade de bloqueios ou transações.
e até chega a dizer:
Usar
LAST_INSERT_ID()
eAUTO_INCREMENT
colunas simultaneamente de vários clientes é perfeitamente válido.
Existem riscos ou cenários conhecidos que podem causar a LAST_INSERT_ID()
não devolução do valor correto?
Estou usando o MySQL 5.5 no CentOS 5.5 x64 e Fedora 16 x64 e no mecanismo InnoDB.
fonte
Para expandir ainda mais o ponto 2 da resposta dada pelo DTest:
Nas versões do MySQL que eu usei, é uma boa idéia redefinir explicitamente o valor de LAST_INSERT_ID antes de cada bloco de código em que você planeja executar uma inserção.
Isso pode ser feito da seguinte maneira:
Após a execução da série de instruções acima, você saberá se a inserção teve algum efeito, verificando se LAST_INSERT_ID ainda estava definido como "some_flag_init_value_of_your_choice" no final da execução.
Caso contrário, você pode acabar com a seguinte situação problemática:
Como a segunda inserção falhou , você pode esperar que a segunda chamada para LAST_INSERT_ID retorne NULL ou que produza um conjunto de resultados vazio (zero linhas). O fato de ainda retornar um identificador inteiro válido pode induzir você a pensar que a segunda inserção foi SUCEDIDA quando não ocorreu.
As coisas ficam MESMO WEIRDER quando você considera que LAST_INSERT_ID continuará preservando e repetindo o último ID exclusivo bem-sucedido, mesmo que as instruções de inserção com falha subsequentes estejam direcionando tabelas diferentes da tabela que produziu o último ID exclusivo bem-sucedido. Em outras palavras, você insere na tabela TA e obtém um ID 5, depois insere na TB (mas falha), mas ainda vê um 5. Com base nisso, você acha que acabou de criar uma nova linha no TA com id de 5 e uma nova linha em TB com id de 5, enquanto que, na realidade, não existe nenhuma linha em TB com id 5 ou existe essa linha, mas na verdade não tem nada a ver com qualquer código que você apenas correu.
fonte
last_insert_id()
para julgar se uma consulta foi bem-sucedida. Afinal, é o último ID inserido, mantendo os valores necessários quando você já sabia que teve sucesso.