Pergunta

Eu tenho uma consulta para inserir uma linha em uma tabela, que tem um campo chamado ID, que é preenchida usando um AUTO_INCREMENT na coluna. Eu preciso para obter este valor para o próximo bit de funcionalidade, mas quando eu executo o seguinte, ele sempre retorna 0, mesmo que o valor real não é 0:

MySqlCommand comm = connect.CreateCommand();
comm.CommandText = insertInvoice;
comm.CommandText += "\'" + invoiceDate.ToString("yyyy:MM:dd hh:mm:ss") + "\', " + bookFee + ", " + adminFee + ", " + totalFee + ", " + customerID +  ")";
int id = Convert.ToInt32(comm.ExecuteScalar());

De acordo com o meu entendimento, isso deve retornar a coluna ID, mas ele só retorna 0 de cada vez. Alguma idéia?

EDIT:

Quando eu executo:

"INSERT INTO INVOICE (INVOICE_DATE, BOOK_FEE, ADMIN_FEE, TOTAL_FEE, CUSTOMER_ID) VALUES ('2009:01:01 10:21:12', 50, 7, 57, 2134);last_insert_id();"

eu recebo:

{"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'last_insert_id()' at line 1"}
Foi útil?

Solução

[Edit: adicionado "selecione" antes das referências para LAST_INSERT_ID ()]

O que sobre a execução de "select last_insert_id();" após sua inserção?

MySqlCommand comm = connect.CreateCommand();
comm.CommandText = insertInvoice;
comm.CommandText += "\'" + invoiceDate.ToString("yyyy:MM:dd hh:mm:ss") + "\', "  
    + bookFee + ", " + adminFee + ", " + totalFee + ", " + customerID +  ");";
    + "select last_insert_id();"

int id = Convert.ToInt32(comm.ExecuteScalar());

Editar: Como duffymo mencionado, você realmente estaria bem servido usando parametrizado consultas como este .


Editar: Até que você mudar para uma versão parametrizada, que você pode encontrar a paz com string.Format:

comm.CommandText = string.Format("{0} '{1}', {2}, {3}, {4}, {5}); select last_insert_id();",
  insertInvoice, invoiceDate.ToString(...), bookFee, adminFee, totalFee, customerID);

Outras dicas

MySqlCommand comm = connect.CreateCommand();
comm.CommandText = insertStatement;  // Set the insert statement
comm.ExecuteNonQuery();              // Execute the command
long id = comm.LastInsertedId;       // Get the ID of the inserted item

Isso me incomoda ver ninguém tomando uma data e armazená-lo em um banco de dados como uma String. Por que não ter o tipo de coluna reflete a realidade?

Eu também estou surpreso de ver uma consulta SQL que está sendo construído usando concatenação. Eu sou um desenvolvedor Java, e eu não sei C # em tudo, mas eu me pergunto se não havia um mecanismo de ligação ao longo das linhas de java.sql.PreparedStatement algum lugar na biblioteca? É recomendado para se proteger contra ataques de injeção SQL. Outro benefício é possíveis benefícios de desempenho, porque o SQL pode ser analisado, verificado, em cache uma vez e reutilizados.

Na verdade, o método ExecuteScalar retorna a primeira coluna da primeira fileira de conjunto de dados sendo devolvido. No seu caso, você está apenas fazendo um Insert, você não está realmente consultar quaisquer dados. Você precisa consultar o SCOPE_IDENTITY () depois que você está inserção (que é a sintaxe para SQL Server) e, em seguida, você terá sua resposta. Veja aqui:

Linkage

EDIT: Como Michael Haren apontou, você mencionou em sua tag que você está usando o MySQL, o uso LAST_INSERT_ID (); em vez de SCOPE_IDENTITY ();

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top