[database] SQLite 테이블에서 마지막 자동 증가 ID를 검색하는 방법은 무엇입니까?

열 ID (기본 키, 자동 증가) 및 콘텐츠 (텍스트)가있는 테이블 메시지가 있습니다.
사용자 이름 (기본 키, 텍스트) 및 해시 열이있는 테이블 사용자가 있습니다.
한 발신자 (사용자)가 여러 수신자 (사용자)에게 메시지를 보내고 수신자 (사용자)는 여러 메시지를 가질 수 있습니다.
MessageID (MessageID (Messages 테이블의 ID 열 참조) 및 Recipient (Users 테이블의 사용자 이름 열 참조)) 열이있는 Messages_Recipients 테이블을 생성했습니다.이 테이블은 수신자와 메시지 간의 다 대다 관계를 나타냅니다.

그래서 제가 가진 질문은 이것입니다. 새 메시지의 ID는 데이터베이스에 저장된 후 생성됩니다. 그러나이 새 MessageID를 검색하기 위해 방금 추가 한 MessageRow에 대한 참조를 어떻게 보유 할 수 있습니까?
물론 마지막으로 추가 된 행을 데이터베이스에서 항상 검색 할 수 있지만 다중 스레드 환경에서 다른 행을 반환 할 수 있습니까?

편집 : 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);
}



답변

SQL Server를 사용하면 현재 프로세스에 대한 마지막 ID 값을 가져 오기 위해 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();
}


답변

또 다른 옵션은 시스템 테이블을 보는 것 sqlite_sequence입니다. 자동 증가 기본 키로 테이블을 생성하면 sqlite 데이터베이스에 자동으로 해당 테이블이 있습니다. 이 테이블은 sqlite가 autoincrement 필드를 추적하여 일부 행을 삭제하거나 일부 삽입이 실패한 후에도 기본 키를 반복하지 않도록하기위한 것입니다 (여기 http://www.sqlite.org/autoinc .html ).

따라서이 테이블을 사용하면 다른 항목을 삽입 한 후에도 새로 삽입 된 항목의 기본 키를 찾을 수 있다는 추가 이점이 있습니다 (물론 다른 테이블에서!). 삽입이 성공했는지 확인한 후 (그렇지 않으면 거짓 번호가 표시됨) 다음을 수행하면됩니다.

select seq from sqlite_sequence where name="table_name"


답변

SELECT last_insert_rowid()다중 스레드 환경에서 사용 하는 데 문제가 있습니다. 다른 스레드가 autoinc가있는 다른 테이블에 삽입하면 last_insert_rowid가 새 테이블에서 autoinc 값을 반환합니다.

여기에 그들이 doco에서 말하는 곳이 있습니다.

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 에 따르면 마지막 삽입 행 ID 가 또 다른 쿼리가 있습니다.

SELECT rowid from your_table_name order by ROWID DESC limit 1


답변