Pregunta

Tengo una consulta para insertar una fila en una tabla, que tiene un campo llamado ID, que se completa utilizando un AUTO_INCREMENTO en la columna. Necesito obtener este valor para el siguiente bit de funcionalidad, pero cuando ejecuto lo siguiente, siempre devuelve 0 aunque el valor real no sea 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());

Según tengo entendido, esto debería devolver la columna ID, pero solo devuelve 0 cada vez. ¿Alguna idea?

EDIT:

Cuando ejecuto:

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

Obtengo:

{"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"}
¿Fue útil?

Solución

[Editar: agregado " seleccione " antes de referencias a last_insert_id ()]

¿Qué hay de ejecutar " select last_insert_id (); " después de su inserción?

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 mencionó duffymo, realmente sería bueno usar consultas parametrizadas así .


Editar: Hasta que cambie a una versión parametrizada, es posible que encuentre paz con la cadena. Formato:

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

Otros consejos

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

Me molesta ver a alguien tomar una Fecha y almacenarla en una base de datos como una Cadena. ¿Por qué no hacer que el tipo de columna refleje la realidad?

También me sorprende ver que se está construyendo una consulta SQL utilizando la concatenación de cadenas. Soy un desarrollador de Java y no conozco C # en absoluto, pero me pregunto si no había un mecanismo de enlace similar a java.sql.PreparedStatement en algún lugar de la biblioteca. Se recomienda para protegerse contra los ataques de inyección SQL. Otro beneficio son los posibles beneficios de rendimiento, porque el SQL puede analizarse, verificarse, almacenarse en caché una vez y reutilizarse.

En realidad, el método ExecuteScalar devuelve la primera columna de la primera fila del DataSet que se devuelve. En su caso, solo está haciendo una inserción, en realidad no está consultando ningún dato. Debe consultar el scope_identity () después de insertar (esa es la sintaxis para SQL Server) y luego tendrá su respuesta. Ver aquí:

Enlace

EDITAR: Como Michael Haren señaló, usted mencionó en su etiqueta que está usando MySql, use last_insert_id (); en lugar de scope_identity ();

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top