web-dev-qa-db-fra.com

Obtenez l'ID de la ligne insérée en utilisant C #

J'ai une requête pour insérer une ligne dans une table, qui a un champ appelé ID, qui est rempli à l'aide d'un AUTO_INCREMENT sur la colonne. J'ai besoin d'obtenir cette valeur pour le bit suivant de fonctionnalité, mais lorsque j'exécute ce qui suit, il renvoie toujours 0 même si la valeur réelle n'est pas 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());

Selon ma compréhension, cela devrait renvoyer la colonne ID, mais il renvoie simplement 0 à chaque fois. Des idées?

MODIFIER:

Quand je cours:

"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();"

Je reçois:

{"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"}
24
Elie

[Edit: ajout de "select" avant les références à last_insert_id ()]

Qu'en est-il de l'exécution de "select last_insert_id();" après votre insertion?

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());

Edit: Comme duffymo l'a mentionné, vous seriez vraiment bien servi en utilisant des requêtes paramétrées comme ça .


Edit: Jusqu'à ce que vous basculiez vers une version paramétrée, vous pourriez trouver la paix avec la chaîne.

comm.CommandText = string.Format("{0} '{1}', {2}, {3}, {4}, {5}); select last_insert_id();",
  insertInvoice, invoiceDate.ToString(...), bookFee, adminFee, totalFee, customerID);
21
Michael Haren
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
39
petra
3
Eli Livshitz

Cela me dérange de voir quelqu'un prendre une date et la stocker dans une base de données sous forme de chaîne. Pourquoi le type de colonne ne reflète-t-il pas la réalité?

Je suis également surpris de voir une requête SQL en cours de création à l'aide de la concaténation de chaînes. Je suis un Java, et je ne connais pas du tout C #, mais je me demande s'il n'y avait pas de mécanisme de liaison similaire à Java.sql.PreparedStatement quelque part dans Elle est recommandée pour se prémunir contre les attaques par injection SQL. Un autre avantage est les avantages possibles en termes de performances, car le SQL peut être analysé, vérifié, mis en cache une seule fois et réutilisé.

0
duffymo

En fait, la méthode ExecuteScalar renvoie la première colonne de la première ligne du DataSet renvoyé. Dans votre cas, vous ne faites qu'une insertion, vous n'interrogez aucune donnée. Vous devez interroger scope_identity () après avoir inséré (c'est la syntaxe de SQL Server) et vous aurez votre réponse. Vois ici:

Lien

EDIT: Comme Michael Haren l'a souligné, vous avez mentionné dans votre balise que vous utilisez MySql, utilisez last_insert_id (); au lieu de scope_identity ();

0
BFree