एंड्रॉइड में डेटाबेस के साथ घूमते हुए, मैं एक बहुत ही अप्रिय बात के बारे में आया: डेटा डालने के लिए SQLiteDatabase विधियां बिल्कुल वैसी ही नहीं हैं जैसी कि दस्तावेज़ में लिखी गई हैं। कार्य सरल था: एक रिकॉर्ड डालें और दूसरी तालिका में उपयोग के लिए इसकी कुंजी प्राप्त करें। यदि आवश्यक रिकॉर्ड पहले से उपलब्ध है, तो मैं इस पुराने रिकॉर्ड की कुंजी जानना चाहता हूं। यह पता चला कि आप इस सबसे पुरानी कुंजी को छोड़कर कुछ भी प्राप्त कर सकते हैं।
इसे समझने के लिए, मुझे बिल्लियों पर कुछ प्रयोग करने थे, लेकिन अब कुछ स्पष्ट हो गया है।
सबसे पहले देखते हैं कि SQLiteDatabase में Android हमसे क्या वादा करता है:
सम्मिलित करना () सबसे आसान तरीका है। यदि कुछ गलत हुआ हो तो सम्मिलित की गई या -1 को वापस करना चाहिए।
InsertOrThrow () - विवरण वास्तव में पिछले एक से मेल खाता है, लेकिन यह जोड़ा जाता है कि विधि एक SQLException फेंकता है। नाम से देखते हुए, हम उम्मीद कर सकते हैं कि SQLException -1 को वापस करने के बजाय फेंक देगा, लेकिन अभी तक कोई निश्चितता नहीं है।
InsertWithOnConflict () - यह सबसे दिलचस्प है। हमें वादा किया जाता है कि विधि नए रिकॉर्ड की कुंजी या मौजूदा रिकॉर्ड की कुंजी को वापस कर देगी यदि IGNORE एल्गोरिथ्म, या -1, संघर्षों के लिए उपयोग किया गया था। यह भी याद रखें कि SQLException के बारे में कुछ नहीं कहा गया है।
अब देखते हैं कि व्यवहार में क्या होता है। आइए एक सरल तालिका बनाएं और इसके लिए (कोई भी नहीं सहित) अलग-अलग संघर्ष रिज़ॉल्यूशन एल्गोरिदम सेट करने का प्रयास करें। मैंने रोलबैक और गर्भपात की जांच नहीं की - इस मामले में उनका व्यवहार, जाहिरा तौर पर, असफल होने के समान होगा, और मुझे सबसे ज्यादा अनदेखी में दिलचस्पी थी।
तालिका में कुछ अद्वितीय मान डालें, और फिर एक परस्पर विरोधी जोड़ने का प्रयास करें। आइए देखें कि ये सभी तरीके संघर्षों को कैसे संभालते हैं।
यदि कोई विरोध रिज़ॉल्यूशन एल्गोरिथ्म निर्दिष्ट नहीं किया गया है, तो सरल सम्मिलित करें () रिटर्न -1 (जैसा वादा किया गया है), और सम्मिलित करेंऑथर () और सम्मिलित करेंWithOnConflict () दोनों एक SQLiteConstraintException फेंक देते हैं। और अगर यह InsertOrThrow () के लिए सही है, तो -1 InsertWithOnConflict () से उम्मीद की जा सकती है। यही बात 'विफल' एल्गोरिथम के साथ होती है।
'बदलें' एल्गोरिदम ने सभी तरीकों को सामान्य रूप से काम किया - उन्होंने पुराने रिकॉर्ड को हटा दिया, एक नया डाला और इसकी कुंजी वापस कर दी।
लेकिन इस तरह के एक आवश्यक 'उपेक्षा' के साथ यह पूरी तरह से गर्म हो गया। तरीकों में से कोई भी एक त्रुटि (-1 या SQLiteConstraintException) फेंक दिया। सभी ने मिलकर एक निश्चित संख्या लौटा दी - संभवतः तालिका में सम्मिलित अंतिम रिकॉर्ड की कुंजी। बेशक, यह बिल्कुल भी नहीं है कि हमसे क्या वादा किया गया था।
सामान्य तौर पर, प्रलेखन पर भरोसा नहीं किया जा सकता है। कोई भी विधि या तो सबसे अप्रत्याशित मान लौटा सकती है या अपवाद फेंक सकती है। लेकिन वांछित परिणाम प्राप्त करना संभव नहीं था - एक संघर्ष में मौजूदा रिकॉर्ड की कुंजी एक भी विधि वापस नहीं कर सकती है।