AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 21181
Accepted
Kev
Kev
Asked: 2012-07-20 09:34:50 +0800 CST2012-07-20 09:34:50 +0800 CST 2012-07-20 09:34:50 +0800 CST

A função LAST_INSERT_ID() do MySql é garantida como correta?

  • 772

Quando faço uma única linha INSERTem uma tabela que possui uma AUTO_INCREMENTcoluna, gostaria de usar a LAST_INSERT_ID()função para retornar o novo AUTO_INCREMENTvalor 'ed armazenado para essa linha.

Como muitos desenvolvedores e administradores do Microsoft SQL Server, sem dúvida, estão cientes de que a funcionalidade equivalente no SQL Server ( SCOPE_IDENTITYe @@IDENTITY) não foi isenta de problemas .

Eu sei que 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_INCREMENTvalor gerado para a declaração mais recente que afeta uma AUTO_INCREMENTcoluna por esse cliente . Este valor não pode ser afetado por outros clientes, mesmo que gerem AUTO_INCREMENTvalores 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.

(fonte)

e até chega a dizer:

Usar LAST_INSERT_ID()e AUTO_INCREMENTcolunas simultaneamente de vários clientes é perfeitamente válido.

(fonte)

Existem riscos ou cenários conhecidos que podem fazer com que LAST_INSERT_ID()não retorne o valor correto?

Estou usando o MySQL 5.5 no CentOS 5.5 x64 e Fedora 16 x64 e o mecanismo InnoDB.

mysql auto-increment
  • 2 2 respostas
  • 65613 Views

2 respostas

  • Voted
  1. Best Answer
    Derek Downey
    2012-07-20T10:07:48+08:002012-07-20T10:07:48+08:00

    Algumas advertências que gostaria de apontar ao usar LAST_INSERT_ID:

    1. Eu sei que você mencionou inserções de linha única. Mas ao fazer inserções de várias linhas, LAST_INSERT_ID()retornará o valor da primeira linha inserida (não a última).

    2. Se a inserção falhou, LAST_INSERT_ID()seria indefinido. O mesmo vale para rollbacks automáticos de transações (devido a erros).

    3. Se você fizer uma inserção em uma transação bem-sucedida e ainda emitir um ROLLBACK, LAST_INSERT_ID()será deixado como estava antes da reversão.

    4. Há algumas advertências ao usar AUTO_INCREMENTe LAST_INSERT_IDna replicação baseada em instrução. O primeiro sendo quando usado em um trigger ou função. O segundo é o cenário menos comum em que sua coluna auto_increment faz parte de uma chave primária composta e não é a primeira coluna da chave.

    • 38
  2. pestophagous
    2012-11-11T11:10:30+08:002012-11-11T11:10:30+08:00

    Para expandir ainda mais o ponto número 2 na resposta dada por DTest:

    Nas versões do MySQL que usei, é uma boa ideia 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 assim:

    -- initialize the LAST_INSERT_ID to some flag value:
    SELECT LAST_INSERT_ID( some_flag_init_value_of_your_choice );
    -- perform the insert  
    INSERT INTO ttt (ccc) VALUES (vvv);
    -- retrieve the id of the inserted row:  
    SELECT LAST_INSERT_ID();
    

    Depois que a série de instruções acima for executada, 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:

    INSERT INTO ttt ( ccc ) VALUES ( 'a' );    -- assume this succeeds.
    SELECT LAST_INSERT_ID();                   -- this will return the unique id of the new row with value 'a'.
    INSERT INTO ttt ( ccc ) VALUES ( 'b' );    -- assume this FAILS.
    SELECT LAST_INSERT_ID();                   -- this will STILL RETURN the unique id of the row with 'a'.
    

    Como a segunda inserção falhou , você pode estar esperando que a segunda chamada para LAST_INSERT_ID retornaria NULL ou produziria um conjunto de resultados vazio (zero linhas). O fato de ele ainda retornar um identificador inteiro válido pode induzir você a pensar que a segunda inserção foi SUCEDIDA quando não o fez.

    As coisas ficam AINDA MAIS ESTRANHAS quando você considera que LAST_INSERT_ID continuará a preservar e repetir o último ID exclusivo bem-sucedido, mesmo se as instruções de inserção com falha subsequentes estiverem 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 de 5, depois insere em 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 na realidade não existe nenhuma linha em TB com id 5, ou existe tal linha, mas na verdade não tem nada a ver com qualquer código que você acabou de correu.

    • 8

relate perguntas

  • Existem ferramentas de benchmarking do MySQL? [fechado]

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • Quando é o momento certo para usar o MariaDB em vez do MySQL e por quê?

  • Como um grupo pode rastrear alterações no esquema do banco de dados?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve