स्ट्रिंग की तुलना करते समय केस असंवेदनशील होने के लिए Sqlite3 कैसे सेट करें?


305

मैं स्ट्रिंग मिलान द्वारा sqlite3 डेटाबेस से रिकॉर्ड का चयन करना चाहता हूं। लेकिन अगर मैं उस खंड में '=' ​​का उपयोग करता हूं, तो मैंने पाया कि sqlite3 संवेदनशील है। क्या कोई मुझे बता सकता है कि केस-असंवेदनशील स्ट्रिंग की तुलना कैसे करें?

जवाबों:


493

आप COLLATE NOCASEअपनी SELECTक्वेरी में उपयोग कर सकते हैं :

SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE

अतिरिक्त, SQLite में, आप इंगित कर सकते हैं कि जब आप collate nocaseस्तंभ की परिभाषा में निर्दिष्ट करके तालिका बनाते हैं तो एक स्तंभ असंवेदनशील होना चाहिए (अन्य विकल्प हैं binary(डिफ़ॉल्ट) और rtrim; यहां देखें )। collate nocaseजब आप एक इंडेक्स भी बना सकते हैं तो आप निर्दिष्ट कर सकते हैं । उदाहरण के लिए:

टेबल टेस्ट बनाएं
(
  Text_Value पाठ कोलाज nocase
);

टेस्ट वैल्यू ('ए') में डालें;
टेस्ट वैल्यू ('बी') में डालें;
टेस्ट वैल्यू ('C') में डालें;

इंडेक्स Test_Text_Value_Index बनाएं
  टेस्ट पर (Text_Value collate nocase);

शामिल Test.Text_Valueहोने वाली अभिव्यक्तियाँ अब असंवेदनशील होनी चाहिए। उदाहरण के लिए:

साइक्लाइट> टेस्ट से Text_Value चुनें जहां Text_Value = 'B';
TEXT_VALUE      
----------------
ख               

sqlite> Text_Value द्वारा टेस्ट ऑर्डर से Text_Value चुनें;
TEXT_VALUE      
----------------
ए               
ख               
सी    

sqlite> Text_Value desc द्वारा टेस्ट ऑर्डर से Text_Value चुनें;
TEXT_VALUE      
----------------
सी               
ख               
ए               

आशावादी व्यक्ति संभवतः केस-असंवेदनशील खोज और स्तंभ पर मिलान के लिए सूचकांक का उपयोग कर सकता है। आप इसे explainSQL कमांड का उपयोग करके देख सकते हैं , जैसे:

sqlite> टेस्ट से Select Text_Value समझाएं जहाँ Text_Value = 'b';
addr opcode p1 P2 p3                               
---------------- -------------- ---------- ---------- ---------------------------------
0 गोटो 0 16                                           
1 इंटजर 0 0                                            
2 OpenRead 1 3 keyinfo (1, NOCASE)                
3 सेटन्यूक्लोमेन्स 1 2                                            
4 स्ट्रिंग 8 0 0 बी                                
५ इसनल -1 १४                                           
6 मेककार्ड 1 0 ए                                
मेमस्टॉर ० ०                                            
8 मूव 1 1 14                                           
९ मेमलवद ० ०                                            
10 IdxGE 1 14 +                                
११ स्तंभ १ ०                                            
१२ कॉलबैक १ ०                                            
१३ अगला १ ९                                            
14 बंद 1 0                                            
१५ हाल्ट ०                                            
१६ लेन-देन ०                                            
१ वेरीच्यूकी ० ४                                            
१ गोटो ० १                                            
१ ९ नूप ०                                            

20
'COLLATE NOCASE' के साथ तालिका बनाने के बाद (पुनः), मैंने देखा कि यह क्वेरी नाम = 'किसी' COLOCATE NOCASE की तुलना में कहीं अधिक तेज है। MUCH तेजी से (छह से 10 बार, मोटे तौर पर?)
DefenestrationDay

10
प्रलेखन के अनुसार, COLLATE NOCASEसूचकांक को जोड़ने की आवश्यकता नहीं है यदि फ़ील्ड में पहले से ही इस कोलाज को परिभाषित किया गया है: " डिफ़ॉल्ट कोलाज़िंग क्रम उस स्तंभ के लिए
बनाए गए

29
COLLATE NOCASEकेवल ASCII पाठ के साथ काम करेगा। आपके कॉलम मूल्यों में "FIANCÉ" या "voilà" होने के बाद, यह "मंगेतर" या "VOILA" के खिलाफ मेल नहीं खाएगा। ICU एक्सटेंशन को सक्षम करने के बाद, LIKEकेस-असंवेदनशील हो 'FIANCÉ' LIKE 'fiancé'जाता है, यह सच है, लेकिन 'VOILA' LIKE 'voilà'अभी भी गलत है। और ICU + LIKE में इंडेक्स का उपयोग न करने की खामी है, इसलिए यह बड़े टेबलों पर धीमा हो सकता है।

div का चयन करें, मामला जब div = 'विफल' हो, तब 'FAIL' और 'PASSED' अंत हो, तो *।
थंडर

7
एक बात ध्यान दें कि मुझे फंसाया गया: select * from tbl where firstname='john' and lastname='doe' COLLATE NOCASEकेस असंवेदनशील होगा lastname। इस पर असंवेदनशील होने के लिए firstname, इसे लिखें select * from tbl where firstname='john' COLLATE NOCASE and lastname='doe':। यह उस एक कॉलम के लिए विशिष्ट है, संपूर्ण whereखंड के लिए नहीं ।
जेम्स टॉमी

148
SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE

5
यदि आप मेरे जैसे हैं और Collating पर अधिक प्रलेखन चाहते हैं, तो आप इसे इस पृष्ठ पर यहां पा सकते हैं: sqlite.org/datatype3.html बस नीचे स्क्रॉल करें # 6.0
विल

47

आप इसे इस तरह से कर सकते हैं:

SELECT * FROM ... WHERE name LIKE 'someone'

(यह समाधान नहीं है , लेकिन कुछ मामलों में बहुत सुविधाजनक है)

" LIKE ऑपरेटर एक पैटर्न मिलान तुलना करता है। दाईं ओर के ऑपरेंड में पैटर्न होता है, बाएं हाथ के ऑपरेंड में पैटर्न के विरुद्ध मिलान करने के लिए स्ट्रिंग होता है। पैटर्न में एक प्रतिशत प्रतीक ("% ") शून्य या अधिक के किसी भी क्रम से मेल खाता है। स्ट्रिंग में वर्ण। पैटर्न में कोई अंडरस्कोर ("_") स्ट्रिंग में किसी एकल वर्ण से मेल खाता हैकोई भी अन्य वर्ण स्वयं या उसके निचले / ऊपरी मामले के बराबर (यानी केस-असंवेदनशील मिलान) से मेल खाता है । (एक बग: SQLite केवल समझता है। ASCII वर्णों के लिए ऊपरी / निचला मामला। LIKE ऑपरेटर यूनिकोड वर्णों के लिए संवेदनशील है जो ASCII श्रेणी से परे है। उदाहरण के लिए, 'a' LIKE 'A' का एक्सप्रेशन TRUE है, लेकिन 'LIKE' AS है।गलत है।)।"


@ MM-BB हाँ, जब तक हम उस कॉलम पर LIKE नहीं करेंगे, जो COLLATE NOCASE के रूप में घोषित (या अनुक्रमित) है, यह पंक्तियों का पूरा स्कैन करेगा।
निक डंडौलकिस 21

1
यह बग नहीं है, यह एक प्रलेखित सीमा है। उत्तर में उद्धृत उसी पृष्ठ में ICU एक्सटेंशन का उल्लेख है जो यूनिकोड वर्णों का प्रबंधन करता है। (शायद 2009 में ऐसा नहीं था)
स्टेंकी

40

यह sqlite के लिए विशिष्ट नहीं है, लेकिन आप बस कर सकते हैं

SELECT * FROM ... WHERE UPPER(name) = UPPER('someone')

प्रदर्शन चिंता का दूसरा हिस्सा तालिका में मिलान पंक्तियों को ढूंढ रहा है। SQLite3 फ़ंक्शन-आधारित इंडेक्स का समर्थन करता है? इस तरह की स्थिति में खोज कॉलम या अभिव्यक्ति (जैसे "UPPER (नाम)") को अनुक्रमित करना आमतौर पर एक अच्छा विचार है।
चेडुअर्दो

13
इस एक के साथ बाहर देखें, क्योंकि चेडियार्डो ने संकेत दिया, इस क्वेरी को चलाते समय SQLite 'नाम' पर एक सूचकांक का उपयोग नहीं कर सकता है। DB इंजन को सभी पंक्तियों को पूर्ण-स्कैन करने की आवश्यकता होगी, सभी 'नाम' फ़ील्ड को ऊपरी मामले में परिवर्तित करना और तुलना चलाना।
मैथ्यू वाटर्स

1
@ योगिता, हाँ, बहुत कुछ।
Berga

4

एक अन्य विकल्प यह है कि आप अपना स्वयं का कस्टम कोलाज बनाएं। फिर आप उस टकराव को स्तंभ पर सेट कर सकते हैं या इसे अपने चुनिंदा खंडों में जोड़ सकते हैं। इसका उपयोग ऑर्डर देने और तुलना करने के लिए किया जाएगा।

इसका इस्तेमाल used VOILA ’LIKE’ voilà ’बनाने के लिए किया जा सकता है।

http://www.sqlite.org/capi3ref.html#sqlite3_create_collation

कोलाजिंग फ़ंक्शन को एक पूर्णांक लौटना चाहिए जो कि ऋणात्मक, शून्य या सकारात्मक है यदि पहला स्ट्रिंग क्रमशः, दूसरे के बराबर या उससे अधिक से कम है।


2

एक अन्य विकल्प जो आपके मामले में समझ में नहीं आता है या नहीं हो सकता है, वह वास्तव में आपके मौजूदा कॉलम के पूर्व-नीच मानों के साथ एक अलग कॉलम है। इसे SQLite फ़ंक्शन का उपयोग करके पॉपुलेट किया जा सकता है LOWER(), और आप इसके बजाय इस कॉलम पर मिलान कर सकते हैं।

जाहिर है, यह अतिरेक और असंगति की क्षमता को जोड़ता है, लेकिन यदि आपका डेटा स्थिर है तो यह एक उपयुक्त विकल्प हो सकता है।


2

बस, आप अपनी पसंद की क्वेरी में COLLATE NOCASE का उपयोग कर सकते हैं:

SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE

1

यदि स्तंभ प्रकार का है, charतो आपको रिक्त स्थान के साथ क्वेरी कर रहे मूल्य को संलग्न करने की आवश्यकता है, कृपया इस प्रश्न को यहां देखें । यह COLLATE NOCASEअन्य समाधानों (ऊपरी (), आदि) का उपयोग करने या करने के अलावा है ।


0

टेबल वैली के साथ संबंधित स्ट्रिंग की तुलना करने के लिए आप क्वेरी की तरह उपयोग कर सकते हैं।

तालिका नाम से कॉलम नाम चुनें जहां कॉलम नाम 'संबंधित तुलना मूल्य';


यह 2009 में पोस्ट किया गया stackoverflow.com/a/973665/2462516 के लिए कुछ भी नहीं जोड़ता है
umasudhan

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.