Question

J'ai une requête pour insérer une ligne dans une table, qui possède un champ appelé ID, qui est renseigné à l'aide de AUTO_INCREMENT sur la colonne. Je dois obtenir cette valeur pour le prochain bit 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());

D'après ce que j'ai compris, cela devrait renvoyer la colonne ID, mais simplement 0. Des idées?

EDIT:

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"}
Était-ce utile?

La solution

[Éditer: ajouté "sélectionnez " avant les références à last_insert_id ()]

Qu'en est-il de l'exécution de " , sélectionnez 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());

Modifier: Comme l'a mentionné le duffymo, l'utilisation de requêtes paramétrées vous serait très utile comme ceci .

Modifier: Jusqu'à ce que vous passiez à une version paramétrée, vous pourriez trouver la paix avec string.Format:

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

Autres conseils

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

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 ne pas faire en sorte que le type de colonne reflète la réalité?

Je suis également surpris de voir une requête SQL en cours de construction à l'aide de la concaténation de chaînes. Je suis un développeur Java et je ne connais pas du tout C #, mais je me demandais s'il n'existait pas de mécanisme de liaison du type java.sql.PreparedStatement quelque part dans la bibliothèque? Il est recommandé de se prémunir contre les attaques par injection SQL. Un autre avantage réside dans les avantages possibles en termes de performances, car le code SQL peut être analysé, vérifié, mis en cache une fois et réutilisé.

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 le scope_identity () après avoir été inséré (c'est la syntaxe pour SQL Server) et ensuite vous aurez votre réponse. Voir ici:

Liaison

MODIFIER: Comme l'a souligné Michael Haren, vous avez mentionné dans votre mot-clé que vous utilisiez MySql, utilisez last_insert_id (); au lieu de scope_identity ();

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top