किसी SQLite तालिका से अंतिम स्वत: संग्रहित ID कैसे प्राप्त करें?


84

मेरे पास कॉलम आईडी (प्राथमिक कुंजी, स्वप्रेरित) और सामग्री (पाठ) के साथ एक तालिका संदेश है।
मेरे पास एक उपयोगकर्ता है जिसमें कॉलम उपयोगकर्ता नाम (प्राथमिक कुंजी, पाठ) और हैश है।
एक संदेश एक प्रेषक (उपयोगकर्ता) द्वारा कई प्राप्तकर्ताओं (उपयोगकर्ता) को भेजा जाता है और एक प्राप्तकर्ता (उपयोगकर्ता) के पास कई संदेश हो सकते हैं।
मैंने दो स्तंभों के साथ एक तालिका Message_Recipients बनाया: MessageID (संदेश तालिका की आईडी स्तंभ और प्राप्तकर्ता (उपयोगकर्ता तालिका में उपयोगकर्ता नाम स्तंभ का जिक्र करते हुए)। यह तालिका प्राप्तकर्ता और संदेशों के बीच कई संबंध का प्रतिनिधित्व करती है।

इसलिए, मेरे पास यह प्रश्न है। डेटाबेस में संग्रहीत होने के बाद एक नए संदेश की आईडी बनाई जाएगी। लेकिन इस नए मैसेजआईडी को पुनः प्राप्त करने के लिए मैं अभी कैसे भेजे गए MessageRow का संदर्भ रख सकता हूं?
मैं पाठ्यक्रम की अंतिम पंक्ति के लिए डेटाबेस को हमेशा खोज सकता हूं, लेकिन यह संभवत: एक अलग वातावरण में एक अलग पंक्ति को वापस कर सकता है?

संपादित करें: जैसा कि मैंने इसे SQLite के लिए समझा है आप इसका उपयोग कर सकते हैं SELECT last_insert_rowid()। लेकिन मैं ADO.Net के इस कथन को कैसे कहूँ?

मेरी दृढ़ता कोड (संदेश और संदेश डेटा प्राप्तकर्ता डेटाटेबल हैं):

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);
}

मैं
SQlite

जवाबों:


88

SQL सर्वर के साथ आप वर्तमान प्रक्रिया के लिए अंतिम पहचान मान प्राप्त करने के लिए 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
फिर से धन्यवाद! दुर्भाग्य से यह अंतिम_insert_rowid () फ़ंक्शन के रूप में काम नहीं करता है क्योंकि डेटाटेबल को बंद करने के लिए उपयोग किए जाने वाले कनेक्शन से पहले फ़ंक्शन को कॉल करने की आवश्यकता होती है। यह हालांकि SQLite का एक
क्विक

1
क्षमा करें, हाँ यह शायद सच है। क्या आपने संदेशों के बाद इसे क्रियान्वित करने का प्रयास किया है Adapter.Update (संदेश);
माइक डब्ल्यू

2
@Dabblernl को लगता है कि एक और उत्तर अधिक विश्वसनीय है, आप स्वीकार किए गए उत्तर को बदलना चाह सकते हैं यदि आपको लगता है कि एक और मददगार है
माइक डब्ल्यूडब्ल्यू

लेकिन RowId हमेशा PRIMARY KEY के समान नहीं होता है। सिवायIf the table has a column of type INTEGER PRIMARY KEY then that column is another alias for the rowid.
Кое Кто

110

एक अन्य विकल्प सिस्टम टेबल को देखना है sqlite_sequence। यदि आपके पास कोई तालिका स्वत: निरूपण प्राथमिक कुंजी के साथ बनाई गई है, तो आपके sqlite डेटाबेस में वह तालिका स्वचालित रूप से होगी। यह तालिका स्वदेशी क्षेत्र का ट्रैक रखने के लिए साइक्लाइट के लिए है ताकि आप कुछ पंक्तियों को हटाने के बाद या कुछ डालने में विफल होने के बाद भी प्राथमिक कुंजी को न दोहराएं (इसके बारे में और अधिक पढ़ें http://www.sqlite.org/autoinchtml )।

तो इस तालिका के साथ जोड़ा गया लाभ है कि आप कुछ और डालने के बाद भी अपनी नई सम्मिलित वस्तु की प्राथमिक कुंजी का पता लगा सकते हैं (अन्य तालिकाओं में!)। यह सुनिश्चित करने के बाद कि आपका इन्सर्ट सफल है (अन्यथा आपको एक गलत नंबर मिलेगा), आपको बस करने की आवश्यकता है:

select seq from sqlite_sequence where name="table_name"

1
यह तब काम करता है जब अनुक्रम बढ़ा हुआ और पंक्ति विलोपन के बाद होता है।
मारेक बार

अच्छा उत्तर। अजीब बात है कि "SQLite के लिए DB ब्राउज़र" यदि "sqlite_fterence" से एक पंक्ति को हटा दें, तो आपको अब किसी तालिका के लिए अंतिम आईडी नहीं मिलेगी।
CoolMind

9

मैं का उपयोग करने के साथ मुद्दों था SELECT last_insert_rowid() एक multithreaded वातावरण में । यदि कोई अन्य थ्रेड किसी अन्य तालिका में सम्मिलित करता है जिसमें एक autoinc है, तो last_insert_rowid नई तालिका से autoinc मान लौटाएगा।

यहां बताया गया है कि वे डोको में कहते हैं:

यदि एक अलग थ्रेड एक ही डेटाबेस कनेक्शन पर एक नया INSERT करता है, जबकि sqlite3_last_insert_rowid () फ़ंक्शन चल रहा है और इस प्रकार अंतिम इन्सर्ट राउड को बदलता है, तो sqlite3_last_in_ster_rowid () द्वारा लौटाया गया मान अप्रत्याशित है और पुराने या नए अंतिम के बराबर नहीं हो सकता है पंक्तिबद्ध डालें।

कि sqlite.org डोको से है


1
मुझे लगता है कि आप प्रत्येक थ्रेड के लिए एक अलग कनेक्शन का उपयोग कर सकते हैं, लेकिन मैंने देखा है कि यह एक बड़ा प्रदर्शन हिट है। मैं अपने परिदृश्य में प्रति सेकंड केवल 15 आवेषण कर सकता हूं।
फिदेल

मेरा अनुमान है कि अलग धागे एक ही मुद्दा होगा। दुर्भाग्य से वहाँ एक थ्रेड-सुरक्षित काम प्रतीत नहीं होता है आज तक, मेरा कूबड़ कई लेन-देन भी पर्याप्त नहीं होगा ... इसलिए सावधान रहें: |
रोजगारपैक

5

@ पॉलीग्लॉट समाधान से नमूना कोड

SQLiteCommand sql_cmd;
sql_cmd.CommandText = "select seq from sqlite_sequence where name='myTable'; ";
int newId = Convert.ToInt32( sql_cmd.ExecuteScalar( ) );

4

Android Sqlite के अनुसार अंतिम सम्मिलित पंक्ति आईडी एक और क्वेरी है:

SELECT rowid from your_table_name order by ROWID DESC limit 1

1
इस विकल्प के पास पंक्तिबद्ध खोजने से पहले एक प्रकार का एल्गोरिथ्म निष्पादित करने के कारण एक प्रदर्शन जुर्माना है
Sr. Libre

2
शायद यह कम इष्टतम है, लेकिन कनेक्शन बंद होने और फिर से खोलने के बाद यह वास्तव में काम करता है, और अन्य दो समाधान मेरे लिए नहीं थे।
फ्रांसिन डेग्रोड टेलर

निम्नलिखित प्रकार से बचा जाता है ORDER BY। तेज होना चाहिए, लेकिन मैंने यह परीक्षण नहीं किया कि:SELECT MAX(rowid) FROM your_table_name
tanius
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.