列ID(プライマリキー、自動インクリメント)およびコンテンツ(テキスト)のテーブルメッセージがあります。
ユーザー名(プライマリキー、テキスト)とハッシュの列を持つテーブルユーザーがあります。
1人の送信者(ユーザー)から多くの受信者(ユーザー)にメッセージが送信され、受信者(ユーザー)は多くのメッセージを持つことができます。
2つの列を持つテーブルMessages_Recipientsを作成しました。MessageID(MessagesテーブルのID列を参照)とRecipient(Usersテーブルのユーザー名列を参照)。メッセージ。
だから、私が持っている質問はこれです。新しいメッセージのIDは、データベースに保存された後に作成されます。しかし、この新しいMessageIDを取得するために、追加したばかりのMessageRowへの参照をどのように保持できますか?
もちろん、追加された最後の行をデータベースでいつでも検索できますが、マルチスレッド環境で異なる行を返す可能性はありますか?
編集:私がSQLiteのためにそれを理解するように、あなたはSELECT last_insert_rowid()
を使うことができます。しかし、ADO.Netからこのステートメントをどのように呼び出すのでしょうか?
私の永続化コード(メッセージと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);
}
SQL Serverでは、SELECT SCOPE_IDENTITY()を使用して、現在のプロセスの最後のID値を取得します。
SQliteを使用すると、自動インクリメントを実行するように見えます
SELECT last_insert_rowid()
挿入直後。
http://www.mail-archive.com/[email protected]/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();
}
もう1つのオプションは、システムテーブルsqlite_sequence
。自動インクリメントの主キーを持つテーブルを作成した場合、sqliteデータベースにはそのテーブルが自動的に作成されます。このテーブルは、sqliteが自動インクリメントフィールドを追跡し、一部の行を削除した後、または一部の挿入が失敗した後でもプライマリキーを繰り返さないようにするためのものです(詳細については、こちらを参照してください http://www.sqlite .org/autoinc.html )。
したがって、このテーブルを使用すると、他のテーブルに(もちろん他のテーブルに)何かを挿入した後でも、新しく挿入したアイテムのプライマリキーを見つけることができるという利点があります。挿入が成功したことを確認した後(そうでない場合は、偽の番号を取得します)、次の手順を実行するだけです。
select seq from sqlite_sequence where name="table_name"
マルチスレッド環境でSELECT last_insert_rowid()
を使用すると問題が発生しました。 autoincを持つ別のテーブルに別のスレッドが挿入されると、last_insert_rowidは新しいテーブルからautoinc値を返します。
彼らがドコでそれを述べる場所は次のとおりです:
Sqlite3_last_insert_rowid()関数の実行中に別のスレッドが同じデータベース接続で新しいINSERTを実行し、したがって最後の挿入ROWIDを変更すると、sqlite3_last_insert_rowid()によって返される値は予測不能で、古いまたは新しい最後のいずれとも等しくない可能性がありますROWIDを挿入します。
sqlite.org doco からです
@polyglotソリューションのサンプルコード
SQLiteCommand sql_cmd;
sql_cmd.CommandText = "select seq from sqlite_sequence where name='myTable'; ";
int newId = Convert.ToInt32( sql_cmd.ExecuteScalar( ) );
Android Sqlite get last insert row id 別のクエリがあります:
SELECT rowid from your_table_name order by ROWID DESC limit 1