2012-11-08 10 views
5

मुझे डेटाबेस से Lämmönmyyntipalvelut शब्द खोजने की आवश्यकता है। केवल, डेटाबेस में यह एक फ़ील्ड में है, जिसका मान एक PHP सरणी है, जो JSON_encode() का उपयोग कर JSON में परिवर्तित हो गया है और इसलिए विशेष वर्ण हेक्स यूनिकोड में स्क्रैबल किए गए हैं।MySQL: यूनिकोड इकाइयों के लिए पूछताछ

तो मेरी क्वेरी

SELECT * FROM table WHERE (services LIKE '%Lämmönmyyntipalvelut%') 

कोई परिणाम नहीं है। कोई आश्चर्य नहीं। इसके बाद, विशेष वर्णों के साथ क्वेरी परिवर्तित:

SELECT * FROM table WHERE (services LIKE '%L\u00e4mm\u00f6nmyyntipalvelut%') 

कोई परिणाम नहीं और मुझे आश्चर्य है कि क्यों। इसके बाद मैंने केवल विशेष चरित्र के लिए पूछताछ की जांच की:

SELECT * FROM table WHERE (services LIKE '%\u00e4%') 

मिला जो मिला था। इसके बाद मैंने यह देखने के लिए सामान (एल शुरू करने के लिए) जोड़ना शुरू किया:

SELECT * FROM table WHERE (services LIKE '%L\u00e4%') 

कोई परिणाम नहीं। एक और परीक्षण:

SELECT * FROM table WHERE (services LIKE '%\u00e4mm%') 

मिला जो मिला था।

तो मेरा निष्कर्ष यह है कि बैकस्लैश किसी चीज को गड़बड़ कर रहा है, लेकिन मुझे समझ में नहीं आता कि कैसे?

संपादित करें: सेवाओं के क्षेत्र की

सटीक सामग्री:

["Neuvonta","L\u00e4mm\u00f6nmyyntipalvelut", 
"Mets\u00e4-\/energiapuunkorjuupalvelut"] 

सटीक क्वेरी:

SELECT id, uid, company_name, services, logo FROM rekisteroeidy_toimijaks 
WHERE 
    (services LIKE '%L\u00e4mm\u00f6nmyyntipalvelut%' AND 
    services LIKE '%Mets\u00e4-\/energiapuunkorjuupalvelut%') 
ORDER BY company_name ASC 

मैं जोड़ा कुछ लाइन पठनीयता मदद करने के लिए टूट जाता है।

+0

'json_encode() 'd परिणाम दिखाएं। –

+0

आपका मतलब है सेवा क्षेत्र की सामग्री? –

+0

हां, शायद कोई उस से देख सकता है, जहां समस्या है। –

उत्तर

7

मैं बिल्कुल पता नहीं क्यों है, लेकिन ट्रिपल एस्केपिंग मदद करता है!

ठीक है, कि केवल डबल एस्केपिंग है, लेकिन हाँ यह काम करता है और यहाँ क्यों है: MySQL में, वहाँ शामिल बचाव जब आप LIKE ऑपरेटर का उपयोग की दूसरी परत है।

services LIKE '%L\\\\u00e4mm\\\\u00f6n%' 

को पार्स कि MySQL स्ट्रिंग शाब्दिक आप की तरह-क्वेरी %L\\u00e4mm\\u00f6n% के साथ तुलना देता है।चूंकि MySQL \ को एक LIKE क्वेरी में भागने के रूप में मानता है, जो वास्तव में L\u00e4mm\u00f6n युक्त शाब्दिक स्ट्रिंग से मेल खाता है।

इसका कारण यह है कि आप एक क्वेरी अभिव्यक्ति के खिलाफ तारों से मेल खा सकते हैं जिसमें एक शाब्दिक % या _ वर्ण शामिल है। उदाहरण के लिए यदि मैं शाब्दिक स्ट्रिंग 100% के लिए कॉलम खोजना चाहता हूं, तो मैं इसे 100\% ('100\\%' के रूप में एक क्वेरी में लिखा गया) के विरुद्ध मिलान कर सकता हूं और सुनिश्चित कर सकता हूं कि मुझे वास्तव में एक सौ प्रतिशत मिल रहा है और केवल सौ से शुरू होने वाली कोई स्ट्रिंग नहीं है।

यह दुर्भाग्यपूर्ण है कि MySQL अपने LIKE क्वेरी से बचने और इसके स्ट्रिंग शाब्दिक भागने के लिए बैकस्लैश का उपयोग करता है, विशेष रूप से यह देखते हुए कि आप शायद एक संलग्न प्रोग्रामिंग भाषा में लिख रहे हैं जो वास्तविक ट्रिपल-एन्कोडिंग के साथ समाप्त होता है, जो दिखता है "services LIKE '%L\\\\\\\\u00e4mm\\\\\\\\u00f6n%'" की तरह - argh!

यह दोगुना दुर्भाग्यपूर्ण है कि यह व्यवहार एएनएसआई एसक्यूएल अनुरूप है, और किसी भी अन्य डेटाबेस में काम नहीं करेगा। ANSI SQL का कहना है वहाँ डिफ़ॉल्ट रूप से की तरह प्रश्नों में कोई भागने चरित्र है, तो आप को नामांकित करने से अपना खुद का एक भागने चरित्र का विकल्प चुनने के लिए है आप एक शाब्दिक % मिलान करना चाहते हैं या _ अगर, उदाहरण के लिए .:

something LIKE '100=%' ESCAPE '=' 

कि क्रॉस-डेटाबेस संगतता के लिए, LIKE ... ESCAPE फ़ॉर्म का उपयोग करना हमेशा सबसे अच्छा है, और भयानक बैकस्लैश के अलावा कुछ और चुनें! (एक तरफ - एसक्यूएल स्ट्रिंग शाब्दिक एस्केपिंग के लिए MySQL के बैकस्लैश नहीं एएनएसआई या तो अनुरूप कर रहे हैं लेकिन आप NO_BACKSLASH_ESCAPES sql_mode सेटिंग के साथ कि दुर्व्यवहार बंद कर सकते हैं।)

शायद एक बेहतर विचार नहीं बल्कि एक दूसरी तालिका में बाहर services तोड़ने के लिए किया जाएगा उन्हें एक स्ट्रिंग कॉलम में स्क्वैश करने से - यानी। अपने सामान्य स्कीमा को अपनी सामान्य फॉर्म में रखें। फिर आप एक धीमी पूर्ण-तालिका-स्कैन सबस्ट्रिंग-मैच करने के बजाय व्यक्तिगत मानों का सरल लुकअप प्राप्त कर सकते हैं।

+0

किसी कारण से बचने से मेरे डेटाबेस में बिल्कुल काम नहीं होता है। मैंने बिनरी के साथ/बिना सभी संयोजनों की कोशिश की और 1 बार से 8 गुना से बच निकला।Utf8mb4_unicode_ci संयोजन के साथ कुछ करना पड़ सकता है। उदाहरण के लिए काम करने का एकमात्र तरीका यह कर रहा था: 'चयन करें * तालिका से चुनें जहां बिनरी कंकैट ('% एल ', यूएनएचएक्स (' सी 3 ए 4 '),' मिमी% ') जैसी सेवाएं; '' बाइनरी अतिरिक्त भी है जरूरी है, या फिर नतीजे बिना 'डायमिसिस' के 'लम' से मेल खाता है। –

+0

@ कपाइटिन विटाबार्ड: यह वास्तविक 'ä' चरित्र (एक यूटीएफ -8 कोलाज मानते हुए) से मेल खाने का एक तरीका है, यदि आप अपने पर्यावरण के सीधे में'% Lämm% 'टाइप नहीं कर सकते हैं। ऐसा नहीं है कि ओपी क्या कर रहा था - वे कुछ धारावाहिक JSON में एक वास्तविक बैकस्लैश से मिलान करने की कोशिश कर रहे थे, न कि शाब्दिक 'ä'। जेएसओएन ने यूनिकोड चरित्र को संदर्भित करने के लिए '\ uNNNN' भाग लिया है; एसक्यूएल अक्षर खुद नहीं करते हैं। – bobince

+1

@ कैपिटेन विटाबार्ड: यदि संभव हो तो तुलना करने के लिए आप जिस संयोजन का उपयोग कर रहे हैं उसमें 'सेवाओं' कॉलम को स्टोर करने के लिए और अधिक कुशल होना चाहिए। यदि आप सटीक पात्रों से मेल खाना चाहते हैं तो यह 'utf8_bin' जैसा 'बिनरी' संयोजन हो सकता है; यदि आप केस-असंवेदनशील लेकिन उच्चारण-संवेदनशील मिलान चाहते हैं जो एक [आश्चर्यजनक रूप से गायब] (https://bugs.mysql.com/bug.php?id=19567) संयोजनों के डिफ़ॉल्ट सेट में संयोजन है, हालांकि कुछ ग़लत हैक इसके आसपास। – bobince

3

बैकस्लैश मेटा चरित्र है, MySQL इसे इस तरह समझता है: "अगले चरित्र को हटाएं और इसे मेटा-कैरेक्टर के रूप में पार्स न करें"।

तो तुम बैकस्लैश से बचने के लिए की जरूरत है: अब

SELECT * FROM table WHERE (services LIKE '%L\\u00e4%') 

, MySQL का स्थान ले लेगा "\\" "\" द्वारा

+0

दुर्भाग्य से मदद नहीं करता है। –

+0

वास्तव में? आपकी "सटीक क्वेरी" में, बैकस्लाश बच नहीं पाए जाते हैं। इस तरह की हर बैकस्लैश से बचने से समस्या हल हो जाती है? : \t चयन आईडी, यूआईडी, company_name, सेवाएं, लोगो rekisteroeidy_toimijaks से कहां (सेवाएं '% L \\ u00e4mm \\ u00f6nmyyntipalvelut%' और सेवाएं जैसे '% मेट्स \\ u00e4 - \\/energiapuunkorjuupalvelut%') कंपनी_नाम द्वारा आदेश एएससी – Vince

+0

वास्तव में, जैसा कि यह अजीब लगता है। तार्किक रूप से आपका उत्तर अच्छा और सही है और समझ में आता है, लेकिन मैंने कोशिश की और यह काम नहीं करता है। –

1
(पहले बैकस्लैश एक मेटा दूसरा एक से बचने के लिए इस्तेमाल किया चरित्र है)

मुझे बिल्कुल कोई जानकारी नहीं है, लेकिन ट्रिपल एस्केपिंग मदद करता है!

SELECT id, uid, company_name, services, logo 
FROM rekisteroeidy_toimijaks 
    WHERE (
    services LIKE '%L\\\\u00e4mm\\\\u00f6n%' 
) 
ORDER BY company_name ASC 
LIMIT 0 , 30 
+1

ऐसा लगता है जैसे आप इसे php, जावा या किसी अन्य भाषा के साथ कर रहे हैं। मुझे पूरा यकीन है, विन्स का जवाब इसके बिना किया गया था। इसलिए, यदि यह मामला है, तो आपको [उसका जवाब स्वीकार करना चाहिए] (http://meta.stackexchange.com/a/5235)। –

+0

लेकिन यह उस भाषा पर निर्भर कैसे हो सकता है जिसका मैं उपयोग कर रहा हूं (यह PHP है, सही है), जब मुझे phpMyAdmin का उपयोग करके बिल्कुल वही व्यवहार मिलता है? –

+0

मैंने अभी कमांड लाइन mysql में यह कोशिश की है और आप सही हैं। मैं उलझन में खड़ा हूं, भ्रम के लिए खेद है। –

संबंधित मुद्दे