我有一个包含列ID(主键,自动增量)和内容(文本)的消息
我有一个表用户名列有用户名(主键,文本)和哈希
一个发件人(用户)向许多收件人(用户)发送邮件,收件人(用户)可以收到许多邮件。
我创建了一个包含两列的表Messages_Recipients:MessageID(引用Messages表的ID列和Recipient(引用Users表中的用户名列)。此表表示收件人和邮件之间的多对多关系。
所以,我的问题是这个。在将新消息存储在数据库中之后,将创建新消息的ID。但是,我怎样才能保留对刚刚添加的MessageRow的引用以便检索这个新的MessageID?
我总是可以在数据库中搜索最后添加的行,但是在多线程环境中可能会返回不同的行?
编辑:据我所知,对于SQLite,您可以使用SELECT last_insert_rowid()
。但是如何从ADO.Net中调用此声明?
我的持久性代码(messages和messagesRecipients是DataTables):
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);
}
答案 0 :(得分:98)
另一个选择是查看系统表sqlite_sequence
。如果您使用自动增量主键创建任何表,则您的sqlite数据库将自动拥有该表。此表用于sqlite跟踪自动增量字段,以便即使在删除某些行或某些插入失败后也不会重复主键(请在此处详细了解http://www.sqlite.org/autoinc.html)。
因此,使用此表可以获得额外的好处,即使在插入其他内容后,您也可以找到新插入的项目的主键(当然,在其他表中!)。在确保插入成功后(否则您将得到一个错误的数字),您只需要执行以下操作:
select seq from sqlite_sequence where name="table_name"
答案 1 :(得分:66)
使用SQL Server,您可以选择SCOPE_IDENTITY()来获取当前进程的最后一个标识值。
使用SQlite,它看起来像你要做的自动增量
SELECT last_insert_rowid()
插入后立即。
http://www.mail-archive.com/sqlite-users@sqlite.org/msg09429.html
在回答你的评论以获得这个值时,你会想要使用SQL或OleDb代码,如:
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();
}
答案 2 :(得分:8)
我在多线程环境中使用SELECT last_insert_rowid()
时遇到了问题。如果另一个线程插入到另一个具有autoinc的表中,则last_insert_rowid将从新表中返回autoinc值。
这是他们在doco中陈述的地方:
如果一个单独的线程在同一个数据库连接上执行新的INSERT,而sqlite3_last_insert_rowid()函数正在运行,从而更改了最后一个insert rowid,那么sqlite3_last_insert_rowid()返回的值是不可预测的,可能不等于旧的或新的最后一个插入rowid。
答案 3 :(得分:5)
来自@polyglot解决方案的示例代码
SQLiteCommand sql_cmd;
sql_cmd.CommandText = "select seq from sqlite_sequence where name='myTable'; ";
int newId = Convert.ToInt32( sql_cmd.ExecuteScalar( ) );
答案 4 :(得分:1)
根据Android Sqlite get last insert row id,还有另一个查询:
SELECT rowid from your_table_name order by ROWID DESC limit 1