Comment récupérer le dernier ID autoincremented à partir d'une table SQLite?

j'ai un tableau Messages avec des colonnes ID (primary key, autoincrement) et contenu (text).

J'ai un utilisateur de table avec le nom d'utilisateur de colonnes (la clé primaire, le texte) et le hachage.

Un message est envoyé par un Expéditeur (utilisateur) à plusieurs destinataires (utilisateur) et un destinataire (utilisateur) peut avoir de nombreux messages.

J'ai créé une table Messages_Recipients avec deux colonnes: MessageID (se référant à la colonne ID de la table Messages et le destinataire (se référant à la colonne username dans le tableau Users). Ce tableau représente la relation de plusieurs à plusieurs entre les destinataires et les messages.

Donc, la question que j'ai est celle-ci. L'ID D'un nouveau message sera créé après avoir été stocké dans la base de données. Mais comment puis-je conserver une référence au message que je viens d'ajouter afin de récupérer ce nouveau MessageID?

je peux toujours rechercher dans la base de données la dernière ligne ajoutée bien sûr, mais cela pourrait éventuellement retourner une rangée différente dans un environnement multithreaded?

EDIT: comme je le comprends pour SQLite, vous pouvez utiliser le SELECT last_insert_rowid() . Mais comment appeler cette déclaration de ADO.Net Je ne sais pas.

mon code de persistance (les messages et les messages sont des données):

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);
}
56
demandé sur O'Neil 2010-01-24 16:07:38

5 réponses

avec SQL Server, vous sélectionnez SCOPE_IDENTITY () pour obtenir la dernière valeur d'identité pour le processus en cours.

avec SQlite, on dirait que pour un auto-engagement vous feriez

SELECT last_insert_rowid()

immédiatement après votre insertion.

http://www.mail-archive.com/sqlite-users@sqlite.org/msg09429.html

dans la réponse à votre commentaire pour obtenir cette valeur, vous souhaitez utiliser SQL ou OleDb code like:

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();
}
56
répondu MikeW 2010-01-25 19:22:54

Une autre option est de regarder la table système sqlite_sequence . Votre base de données sqlite aura cette table automatiquement si vous avez créé n'importe quelle table avec la clé primaire d'auto-engagement. Cette table est pour sqlite de garder la trace du champ autoincrement de sorte qu'il ne répétera pas la clé primaire même après que vous supprimez quelques lignes ou après un insert échoué (lire plus à ce sujet ici http://www.sqlite.org/autoinc.html ).

donc avec cette table là est l'avantage que vous pouvez trouver votre nouvellement inséré l'élément clé primaire, même après que vous avez inséré quelque chose d'autre (dans d'autres tableaux, bien sûr!). Après vous être assuré que votre insert est réussi (sinon vous obtiendrez un faux numéro), il vous suffit de faire:

select seq from sqlite_sequence where name="table_name"
91
répondu polyglot 2010-02-07 14:13:39

j'ai eu des problèmes avec l'utilisation de SELECT last_insert_rowid() dans un environnement multithread. Si un autre thread s'insère dans une autre table qui a un autoinc, last_insert_rowid retournera la valeur autoinc de la nouvelle table.

voici où ils déclarent que dans le doco:

si un thread séparé effectue une nouvelle insertion sur la même connexion de base de données alors que la fonction sqlite3_last_insert_rowid() est en cours d'exécution et modifie ainsi la dernière insertion rowid, alors la valeur retournée par sqlite3_last_insert_rowid() est imprévisible et peut ne pas être égale à l'ancienne ou à la nouvelle dernière insertion rowid.

c'est de sqlite.org doco

8
répondu Fidel 2010-01-30 06:40:27

exemple de code de @polyglot solution

SQLiteCommand sql_cmd;
sql_cmd.CommandText = "select seq from sqlite_sequence where name='myTable'; ";
int newId = Convert.ToInt32( sql_cmd.ExecuteScalar( ) );
4
répondu Yosemite Sam 2018-08-28 22:01:39

selon Android Sqlite dernière insertion id de ligne il y a une autre requête:

SELECT rowid from your_table_name order by ROWID DESC limit 1
0
répondu CoolMind 2018-08-21 15:10:16