Obter o ID da linha inserida usando C #
-
03-07-2019 - |
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"}
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
Use LastInsertedId.
Ver a minha sugestão com o exemplo aqui: http://livshitz.wordpress.com/2011/10/28/returning-last-inserted-id-in-c-using-mysql-db-provider/
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:
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 ();