2013-02-24 64 views
5

पर स्थानीयकृत COLLATE मैं लहजे और मामले की देखभाल किए बिना SQLite डीबी में दो तारों की तुलना करना चाहता हूं। मेरा मतलब है "एवेनमेंट" "उत्थान" के बराबर होना चाहिए।एक SQLite स्ट्रिंग तुलना

डेबियन व्हीज़ी पर, SQLite पैकेज आईसीयू प्रदान नहीं करता है। इसलिए मैंने आधिकारिक SQLite पैकेज (संस्करण 3.7.15.2 2013-01-09 11:53:05) संकलित किया जिसमें आईसीयू मॉड्यूल शामिल है। अब, मेरे पास एक बेहतर यूनिकोड समर्थन है (मूल lower() केवल ASCII वर्णों पर लागू होता है, अब यह अन्य अक्षरों पर काम करता है)। लेकिन मैं तुलना में एक संयोजन लागू करने के लिए प्रबंधन नहीं कर सकता।

SELECT icu_load_collation('fr_FR', 'FRENCH'); 
SELECT 'événement' COLLATE FRENCH = 'evenement'; 
-- 0 (should be 1) 
SELECT 'Événement' COLLATE FRENCH = 'événement'; 
-- 0 (should be 1 if collation was case-insensitive) 
SELECT lower('Événement') = 'événement'; 
-- 1 (at least lower() works as expected with Unicode strings) 

SQLite documentation पुष्टि करता है कि यह एक संयोजन लागू करने का सही तरीका है। मुझे लगता है कि documentation of this ICU extension थोड़ा हल्का है (कुछ उदाहरण, कॉलेशन के लिए संवेदनशीलता पर कुछ भी नहीं)।

मुझे समझ में नहीं आता कि COLLATE ऑपरेटर का मेरे उदाहरण में कोई प्रभाव क्यों नहीं है। कृपया मदद करे।

उत्तर

5

मैं मेरे घंटे लगे स्थिति ... जिस तरह से आईसीयू collations तुलना पर है (लगभग) कोई घटना SQLite में परिभाषित कर रहे हैं समझने के लिए। आईसीयू के मुताबिक, अपवाद के निशान के साथ हिब्रू ग्रंथों का अपवाद है। यह आईसीयू लाइब्रेरी के संयोजन का डिफ़ॉल्ट व्यवहार है। SQLite के साथ, LIKE आईसीयू लोड होने पर केस-असंवेदनशील हो जाता है, लेकिन accentuated अक्षरों का सामान्यीकरण इस तरह से प्राप्त नहीं किया जा सकता है।

मैं अंत में समझ गया कि मैं क्या जरूरत primary level डिफ़ॉल्ट तृतीयक स्तर के बजाय को strength मिलान की स्थापित करने के लिए किया गया था।

मैं स्थान (SELECT icu_load_collation('fr_FR,strength=0', 'french') का उदाहरण के कई वेरिएंट बेकार थे) के माध्यम से इस सेट करने के लिए कोई रास्ता नहीं मिला। तो एकमात्र समाधान SQLite के कोड को पैच करना था। ICU API में ucol_setStrength() फ़ंक्शन का आसान धन्यवाद था।

न्यूनतम परिवर्तन एक लाइन पैच है: pUCollator = ucol_open(zLocale, &status); के बाद icuLoadCollation() में लाइन जोड़ें। पीछे की तरफ-संगत परिवर्तन के लिए, मैंने icu_load_collation() पर एक वैकल्पिक तीसरा पैरामीटर जोड़ा जो ताकत सेट करता है: 0 डिफ़ॉल्ट रूप से, प्राथमिक के लिए 1, आदि 4-क्वाटरनेरी तक। diff देखें।

अंत में मैं मैं चाहता था है:

SELECT icu_load_collation('fr_FR', 'french_ci', 1); -- collation with strength=primary 
SELECT 'Événement' COLLATE french_ci = 'evenèment'; 
-- 1