Tengo una tabla de Mensajes con ID de columnas (clave principal, autoincremento) y Contenido (texto).
Tengo una tabla de Usuarios con columnas de nombre de usuario (clave principal, texto) y Hash.
Un remitente (usuario) envía un mensaje a muchos destinatarios (usuario) y un destinatario (usuario) puede tener muchos mensajes.
Creé una tabla Messages_Recipients con dos columnas: MessageID (refiriéndose a la columna ID de la tabla Messages y Recipient (refiriéndose a la columna de nombre de usuario en la tabla Users). Esta tabla representa la relación de muchos a muchos entre destinatarios y mensajes.
Entonces, la pregunta que tengo es esta. El ID de un mensaje nuevo se creará después de que se haya almacenado en la base de datos. Pero, ¿cómo puedo tener una referencia al MessageRow que acabo de agregar para recuperar este nuevo MessageID?
Siempre puedo buscar en la base de datos la última fila agregada, por supuesto, pero ¿eso podría devolver una fila diferente en un entorno multiproceso?
EDITAR: Según tengo entendido para SQLite, puede usar SELECT last_insert_rowid()
. Pero, ¿cómo llamo a esta declaración de ADO.Net?
Mi código de persistencia (los mensajes y los destinatarios de los mensajes son tablas de datos):
public void Persist(Message message)
{
pm_databaseDataSet.MessagesRow messagerow;
messagerow=messages.AddMessagesRow(message.Sender,
message.TimeSent.ToFileTime(),
message.Content,
message.TimeCreated.ToFileTime());
UpdateMessages();
var x = messagerow;//I hoped the messagerow would hold a
//reference to the new row in the Messages table, but it does not.
foreach (var recipient in message.Recipients)
{
var row = messagesRecipients.NewMessages_RecipientsRow();
row.Recipient = recipient;
//row.MessageID= How do I find this??
messagesRecipients.AddMessages_RecipientsRow(row);
UpdateMessagesRecipients();//method not shown
}
}
private void UpdateMessages()
{
messagesAdapter.Update(messages);
messagesAdapter.Fill(messages);
}
fuente
Respuestas:
Con SQL Server, SELECCIONE SCOPE_IDENTITY () para obtener el último valor de identidad para el proceso actual.
Con SQlite, parece que para un autoincremento harías
SELECT last_insert_rowid()
inmediatamente después de su inserción.
http://www.mail-archive.com/[email protected]/msg09429.html
En respuesta a su comentario para obtener este valor, querrá usar código SQL u OleDb como:
using (SqlConnection conn = new SqlConnection(connString)) { string sql = "SELECT last_insert_rowid()"; SqlCommand cmd = new SqlCommand(sql, conn); conn.Open(); int lastID = (Int32) cmd.ExecuteScalar(); }
fuente
If the table has a column of type INTEGER PRIMARY KEY then that column is another alias for the rowid.
Otra opción es mirar la tabla del sistema
sqlite_sequence
. Su base de datos sqlite tendrá esa tabla automáticamente si creó cualquier tabla con clave primaria de autoincremento. Esta tabla es para que sqlite realice un seguimiento del campo de autoincremento para que no repita la clave principal incluso después de eliminar algunas filas o después de que fallara alguna inserción (lea más sobre esto aquí http://www.sqlite.org/autoinc .html ).Entonces, con esta tabla existe el beneficio adicional de que puede encontrar la clave principal de su elemento recién insertado incluso después de haber insertado algo más (¡en otras tablas, por supuesto!). Después de asegurarse de que su inserción sea correcta (de lo contrario, obtendrá un número falso), simplemente debe hacer:
select seq from sqlite_sequence where name="table_name"
fuente
He tenido problemas con el uso
SELECT last_insert_rowid()
en un entorno multiproceso. Si otro hilo se inserta en otra tabla que tiene un autoinc, last_insert_rowid devolverá el valor autoinc de la nueva tabla.Aquí es donde afirman que en el doco:
Eso es de sqlite.org doco
fuente
Código de muestra de la solución @polyglot
SQLiteCommand sql_cmd; sql_cmd.CommandText = "select seq from sqlite_sequence where name='myTable'; "; int newId = Convert.ToInt32( sql_cmd.ExecuteScalar( ) );
fuente
Según Android Sqlite, obtenga la última identificación de fila de inserción, hay otra consulta:
SELECT rowid from your_table_name order by ROWID DESC limit 1
fuente
ORDER BY
. Debería ser más rápido, pero noSELECT MAX(rowid) FROM your_table_name