Domanda

Ho una query per inserire una riga in una tabella, che ha un campo chiamato ID, che viene popolato usando un AUTO_INCREMENT sulla colonna. Ho bisogno di ottenere questo valore per il prossimo bit di funzionalità, ma quando eseguo quanto segue, restituisce sempre 0 anche se il valore effettivo non è 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());

Secondo la mia comprensione, questo dovrebbe restituire la colonna ID, ma restituisce solo 0 ogni volta. Qualche idea?

Modifica

Quando corro:

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

Ottengo:

{"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"}
È stato utile?

Soluzione

[Modifica: aggiunto " seleziona " prima di riferimenti a last_insert_id ()]

Che dire di eseguire " selezionare last_insert_id (); " dopo il tuo inserimento?

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

Modifica: Come accennato da duffymo, saresti davvero ben servito usando query con parametri come questo .


Modifica: Fino a quando non passi a una versione con parametri, potresti trovare la pace con string.Format:

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

Altri suggerimenti

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

Usa LastInsertedId.

Visualizza il mio suggerimento con l'esempio qui: http://livshitz.wordpress.com/2011/10/28/returning-last-inserted-id-in-c-using-mysql-db-provider/

Mi dà fastidio vedere qualcuno che prende una data e la memorizza in un database come una stringa. Perché il tipo di colonna non riflette la realtà?

Sono anche sorpreso di vedere una query SQL che viene creata utilizzando la concatenazione di stringhe. Sono uno sviluppatore Java e non conosco affatto C #, ma mi chiedo se non ci fosse un meccanismo di associazione lungo le linee di java.sql.PreparedStatement da qualche parte nella libreria? È consigliato per proteggersi dagli attacchi di iniezione SQL. Un altro vantaggio sono i possibili vantaggi in termini di prestazioni, poiché l'SQL può essere analizzato, verificato, memorizzato nella cache una volta e riutilizzato.

In realtà, il metodo ExecuteScalar restituisce la prima colonna della prima riga del DataSet da restituire. Nel tuo caso, stai solo eseguendo un inserimento, non stai effettivamente interrogando alcun dato. Devi interrogare scope_identity () dopo aver inserito (che è la sintassi di SQL Server) e avrai la tua risposta. Vedi qui:

Linkage

EDIT: Come ha sottolineato Michael Haren, nel tuo tag hai menzionato che stai usando MySql, usa last_insert_id (); anziché scope_identity ();

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top