SQL सर्वर जहाँ अभिव्यक्ति में मामले को अनदेखा करता है


88

मैं एक SQL क्वेरी (MS SQL सर्वर) का निर्माण कैसे करता हूं, जहां "जहां" खंड केस-असंवेदनशील है?

SELECT * FROM myTable WHERE myField = 'sOmeVal'

मैं चाहता हूं कि परिणाम मामले की अनदेखी करके वापस आएं

जवाबों:


135

एक SQL सर्वर डेटाबेस का डिफ़ॉल्ट विन्यास में, स्ट्रिंग तुलना कर रहे हैं केस-संवेदी। यदि आपका डेटाबेस इस सेटिंग (एक वैकल्पिक टकराव के उपयोग के माध्यम से) को ओवरराइड करता है, तो आपको यह निर्दिष्ट करने की आवश्यकता होगी कि आपकी क्वेरी में किस प्रकार के कोलाज का उपयोग करना है।

SELECT * FROM myTable WHERE myField = 'sOmeVal' COLLATE SQL_Latin1_General_CP1_CI_AS

ध्यान दें कि मेरे द्वारा प्रदान किया गया कोलाजेशन केवल एक उदाहरण है (हालांकि यह आपके लिए संभावित फ़ंक्शन से अधिक होगा)। SQL सर्वर collations की अधिक गहन रूपरेखा यहाँ मिल सकती है


बस पुष्टि करने के लिए, यह केवल WHEREबयान के अंत में एक बार जोड़ा जाना चाहिए , और सभी WHEREखंडों को प्रभावित करेगा , सही?
ashleedawg

यह जानने के लिए कि क्या आपके उत्तर में खोज के लिए किसी स्तंभ मान को केस UPPERया LOWERकेस में परिवर्तित करके कोई प्रदर्शन समस्या है LIKE?
शाइजुत

1
@ashleedawg - अच्छा सवाल .. यह एक प्रति-पंक्ति सेटिंग प्रतीत होता है।
लियो गुरदियन

29

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

SELECT balance FROM people WHERE email = 'billg@microsoft.com'
  COLLATE SQL_Latin1_General_CP1_CI_AS 

@AskeB। और वृषभ: यह तकनीकी रूप से एक डेटाबेस कॉन्फ़िगरेशन समस्या नहीं है। कृपया स्ट्रिंग तुलना पर स्पष्टीकरण के लिए मेरा जवाब देखें ।
सोलोमन रटज़की

21

मुझे एक और समाधान कहीं और मिला; वह है, उपयोग करने के लिए

upper(@yourString)

लेकिन यहां हर कोई कह रहा है कि, SQL सर्वर में, यह कोई फर्क नहीं पड़ता क्योंकि यह वैसे भी मामले की अनदेखी कर रहा है? मुझे पूरा यकीन है कि हमारा डेटाबेस केस-संवेदी है।


6
आप सही हैं कि डेटाबेस को संवेदनशील बनाया जा सकता है, लेकिन यह बहुत ही अक्षम है, भले ही इसकी आवश्यकता हो। COLLATE का उपयोग करने के लिए कीवर्ड है।
मझगार्ड

1
कि ऊपर लाने के लिए धन्यवाद, @mjaggard। मुझे आशा है कि आप, या कोई भी जो मेरे उत्तर को कम करने के लिए लगता है, अपने जैसे किसी भी व्यक्ति की भलाई के लिए विस्तृत है जो मेरे बारे में खोजता है और उत्तर पाता है।
डैनी

1
यह पूरी तरह तर्कसंगत व्याख्या है। बहुत अधिक ओवरहेड के ढेर को समेटें और क्या होगा अगर आपके तार में इसके पात्र हैं जो कि टकराव समझ में नहीं आता है? लैटिन 1 एक घटिया एन्कोडिंग योजना है। अगर आपके तार में एक एपोस्ट्रोप है (तो ओ'ब्रायन) में अच्छे परिणाम प्राप्त करना सौभाग्य की बात है।
एग्मैटर्स

2
साथ ही अपग्रेड किया गया। मैं बहुत सारे मामलों के बारे में सोच सकता हूं जहां यह उपयोगी होगा। इसके अतिरिक्त, अक्सर कुछ करने के लिए एक से अधिक अच्छे तरीके होते हैं।
इन्वर्सस

1
तुलनात्मक उद्देश्यों के लिए स्ट्रिंग के मामले को बदलना आम तौर पर बुरा है। कुछ भाषाओं के मामले में रूपांतरण गोल-यात्रा नहीं करते हैं। यानी LOWER (x)! = LOWER (UPPER (x))।
Ceisc

14

शीर्ष 2 उत्तर ( एडम रॉबिन्सन और बेन्स कैनिकोव्स से ) थोड़े हैं, सॉर्ट सही हैं, इसमें वे तकनीकी रूप से काम करते हैं, लेकिन उनकी व्याख्या गलत है और इसलिए कई मामलों में भ्रामक हो सकती है। उदाहरण के लिए, जबकि SQL_Latin1_General_CP1_CI_ASटकराव कई मामलों में काम करेगा, इसे उचित मामला-असंवेदनशील टकराव नहीं माना जाना चाहिए। वास्तव में, यह देखते हुए कि ओपी एक केस-संवेदी (या संभवतः बाइनरी) कॉलेशन के साथ एक डेटाबेस में काम कर रहा है, हम जानते हैं कि ओपी उस कॉलेशन का उपयोग नहीं कर रहा है जो इतने सारे इंस्टॉलेशन के लिए डिफ़ॉल्ट है (विशेष रूप से किसी ओएस पर स्थापित) भाषा के रूप में यूएस अंग्रेजी का उपयोग करना) SQL_Latin1_General_CP1_CI_AS:। बेशक, ओपी का उपयोग किया जा सकता है SQL_Latin1_General_CP1_CS_AS, लेकिन जब साथ काम कर रहा हैVARCHARडेटा, कोड पृष्ठ को नहीं बदलना महत्वपूर्ण है क्योंकि यह डेटा हानि का कारण बन सकता है, और इसे नियंत्रण के स्थानीय / संस्कृति द्वारा नियंत्रित किया जाता है (यानी लैटिन 1_General बनाम फ्रेंच बनाम हिब्रू आदि)। कृपया नीचे बिंदु # 9 देखें।

अन्य चार उत्तर अलग-अलग डिग्री के लिए गलत हैं।

मैं यहां सभी गलतफहमी को स्पष्ट कर दूंगा ताकि पाठक सबसे उपयुक्त / कुशल विकल्प चुन सकें।

  1. उपयोग न करें UPPER()। यह पूरी तरह से अनावश्यक अतिरिक्त काम है। एक COLLATEक्लॉज का उपयोग करें । एक स्ट्रिंग तुलना को किसी भी मामले में किए जाने की आवश्यकता होती है, लेकिन UPPER()यह भी देखने के लिए कि चरित्र द्वारा चरित्र की जांच करना है, यह देखने के लिए कि क्या कोई ऊपरी-मामला मानचित्रण है, और फिर इसे बदल दें। और आपको दोनों तरफ ऐसा करने की आवश्यकता है। जोड़ा जा रहा है COLLATEबस नियमों का एक अलग सेट की तुलना में यह डिफ़ॉल्ट रूप से जा रहा था का उपयोग कर तरह कुंजी उत्पन्न करने के लिए प्रसंस्करण निर्देश देता है। का उपयोग करना COLLATEनिश्चित रूप से अधिक कुशल है (या " परफ़ॉर्मेंट ", यदि आपको वह शब्द पसंद है :) का उपयोग करने की तुलना में UPPER(), जैसा कि इस परीक्षण स्क्रिप्ट में साबित किया गया है (पेस्टबिन पर)

    @ डैनी के उत्तर पर @Ceisc द्वारा नोट किया गया मुद्दा भी है :

    कुछ भाषाओं के मामले में रूपांतरण गोल-यात्रा नहीं करते हैं। यानी LOWER (x)! = LOWER (UPPER (x))।

    तुर्की ऊपरी मामला "İ" सामान्य उदाहरण है।

  2. नहीं, टकराव एक डेटाबेस-वाइड सेटिंग नहीं है, कम से कम इस संदर्भ में नहीं। एक डेटाबेस-लेवल डिफ़ॉल्ट कॉलेशन है, और इसका उपयोग परिवर्तित और नए बनाए गए स्तंभों के लिए डिफ़ॉल्ट के रूप में किया जाता है COLLATEजो क्लॉज़ को निर्दिष्ट नहीं करते हैं (जो संभवतः यह सामान्य गलत धारणा है), लेकिन यह सीधे प्रश्नों पर प्रभाव नहीं डालता है जब तक आप नहीं हैं स्ट्रिंग स्ट्रिंग और वेरिएबल्स की तुलना अन्य स्ट्रिंग लिटरल और वैरिएबल्स या आप डेटाबेस-स्तर मेटा-डेटा के संदर्भ में कर रहे हैं।

  3. नहीं, टक्कर प्रति प्रश्न नहीं है।

  4. कोलायत विधेय के अनुसार प्रतिगामी (यानी कुछ परिचालित कुछ) या अभिव्यक्ति हैं। और यह पूरे क्वेरी के लिए सही है, न कि केवल WHEREक्लॉज के लिए। इसमें JOINs, GROUP BY, ORDER BY, पार्टीशन BY आदि शामिल हैं।

  5. नहीं, निम्न कारणों से VARBINARY(जैसे convert(varbinary, myField) = convert(varbinary, 'sOmeVal')) में परिवर्तित न करें :

    1. यह एक द्विआधारी तुलना है, जो केस-असंवेदनशील नहीं है (जो कि यह प्रश्न पूछ रहा है)
    2. यदि आप बाइनरी तुलना चाहते हैं, तो बाइनरी कॉलेशन का उपयोग करें। _BIN2यदि आप SQL Server 2008 या नए का उपयोग कर रहे हैं, तो एक का उपयोग करें , अन्यथा आपके पास समाप्त होने वाले एक का उपयोग करने के अलावा कोई विकल्प नहीं है _BIN। यदि डेटा है NVARCHARतो इससे कोई फर्क नहीं पड़ता कि आप किस लोकेल का उपयोग करते हैं क्योंकि वे उस मामले में सभी समान हैं, इसलिए Latin1_General_100_BIN2हमेशा काम करता है। डेटा है VARCHAR, आप एक ही स्थान का उपयोग करना चाहिए कि डेटा (जैसे में है Latin1_General, French, Japanese_XJIS, आदि) क्योंकि वातावरण है कि प्रयोग किया जाता है कोड पेज को निर्धारित करता है, और कोड पृष्ठों को बदलने डेटा (यानी डेटा हानि) बदल सकते हैं।
    3. आकार निर्दिष्ट किए बिना एक चर-लंबाई डेटाटाइप का उपयोग करना डिफ़ॉल्ट आकार पर निर्भर करेगा, और उस संदर्भ के आधार पर दो अलग-अलग चूक हैं जहां डेटाटाइप का उपयोग किया जा रहा है। यह स्ट्रिंग प्रकारों के लिए 1 या 30 है। जब इसके साथ उपयोग किया जाता है CONVERT()तो 30 डिफ़ॉल्ट मूल्य का उपयोग करेगा। खतरा यह है, अगर स्ट्रिंग 30 बाइट्स से अधिक हो सकती है, तो यह चुपचाप काट दिया जाएगा और आपको संभवतः इस विधेय से गलत परिणाम मिलेंगे।
    4. यहां तक कि अगर आप एक केस-संवेदी तुलना करना चाहते हैं, द्विआधारी collations हैं नहीं केस-संवेदी (एक और बहुत आम धारणा है)।
  6. नहीं, LIKEहमेशा केस-संवेदी नहीं होता है। यह संदर्भित किए जा रहे कॉलम के कोलाजेशन का उपयोग करता है, या डेटाबेस का टकराव अगर किसी स्ट्रिंग शाब्दिक, या वैकल्पिक COLLATEक्लॉज के माध्यम से निर्दिष्ट कोलाज की तुलना करता है ।

  7. LCASESQL सर्वर फ़ंक्शन नहीं है। यह Oracle या MySQL प्रतीत होता है। या संभवतः विजुअल बेसिक?

  8. चूँकि प्रश्न का संदर्भ किसी स्तंभ को स्ट्रिंग शाब्दिक से तुलना कर रहा है, न तो उदाहरण का टकराव (अक्सर "सर्वर" के रूप में जाना जाता है) और न ही डेटाबेस के टकराव का यहां कोई सीधा प्रभाव पड़ता है। कोलाज प्रत्येक कॉलम में संग्रहीत किए जाते हैं, और प्रत्येक कॉलम में एक अलग कोलाजेशन हो सकता है, और उन कोलाज को डेटाबेस के डिफ़ॉल्ट कोलाजेशन या इंस्टेंस के कोलाजेशन के समान होने की आवश्यकता नहीं होती है। निश्चित रूप से, उदाहरण कोलाजेशन एक नए बनाए गए डेटाबेस के लिए डिफ़ॉल्ट है जो डेटाबेस COLLATEबनाते समय यदि क्लॉज निर्दिष्ट नहीं किया गया था , तो यह उसके डिफ़ॉल्ट टकराव के रूप में उपयोग करेगा । और इसी तरह, डेटाबेस का डिफॉल्ट कॉलेशन वह है जो परिवर्तित या नए बनाए गए कॉलम का उपयोग करेगा यदि COLLATEक्लॉज निर्दिष्ट नहीं किया गया था।

  9. आपको केस-असंवेदनशील कोलाजेशन का उपयोग करना चाहिए जो अन्यथा स्तंभ के टकराव के समान है। स्तंभ के टकराने (तालिका का नाम और स्कीमा नाम बदलें) को खोजने के लिए निम्नलिखित क्वेरी का उपयोग करें:

    SELECT col.*
    FROM   sys.columns col
    WHERE  col.[object_id] = OBJECT_ID(N'dbo.TableName')
    AND    col.[collation_name] IS NOT NULL;
    

    तो बस _CSहोने के लिए बदल जाते हैं _CI। तो, Latin1_General_100_CS_ASबन जाएगा Latin1_General_100_CI_AS

    स्तंभ एक द्विआधारी मिलान (में समाप्त होने वाले उपयोग कर रहा है _BINया _BIN2), तो निम्न क्वेरी का उपयोग कर एक समान मिलान पाते हैं:

    SELECT *
    FROM   sys.fn_helpcollations() col
    WHERE  col.[name] LIKE N'{CurrentCollationMinus"_BIN"}[_]CI[_]%';
    

    उदाहरण के लिए, मान लें कि कॉलम उपयोग कर रहा है Japanese_XJIS_100_BIN2, ऐसा करें:

    SELECT *
    FROM   sys.fn_helpcollations() col
    WHERE  col.[name] LIKE N'Japanese_XJIS_100[_]CI[_]%';
    

Collations , encodings, आदि के बारे में अधिक जानकारी के लिए, कृपया देखें: Collations Info


7

नहीं, केवल उपयोग करने LIKEसे काम नहीं चलेगा। LIKEआपके दिए गए पैटर्न से मिलते-जुलते मूल्य खोजता है। इस मामले में LIKEकेवल पाठ 'sOmeVal' और 'कुछ' नहीं मिलेगा।

एक pracitcable समाधान LCASE()फ़ंक्शन का उपयोग कर रहा है। LCASE('sOmeVal')आपके पाठ का निचला भाग मिलता है: 'कुछ'। यदि आप अपनी तुलना के दोनों ओर इस फ़ंक्शन का उपयोग करते हैं, तो यह काम करता है:

SELECT * FROM myTable WHERE LCASE(myField) LIKE LCASE('sOmeVal')

बयान दो लोअरकेस स्ट्रिंग्स की तुलना करता है, ताकि आपका 'सॉमेवैल' 'कुछ' (जैसे 'कुछ', 'कुछ' इत्यादि) के हर दूसरे अंकन से मेल खाए।


7
SQL सर्वर प्रतिष्ठानों के 99.9% में जो _CI से टकराए हैं, LIKE केस असंवेदनशील है।
रिचर्ड द किवी

1
आजकल समारोह को
डेविड ब्रॉसार्ड

@ डेविडबॉर्ड और डेविड हर्मन, मुझे नहीं लगता कि यह LCASE()एसक्यूएल सर्वर में कभी था (कम से कम ऐसा नहीं जिसे मैं देख सकता हूं)। मुझे लगता है कि यह उत्तर पूरी तरह से अलग RDBMS के लिए है। कृपया स्ट्रिंग तुलना पर स्पष्टीकरण के लिए मेरा जवाब देखें ।
सोलोमन रटज़की

4

आप केस को संवेदनशील बनाने के लिए बाध्य कर सकते हैं, जैसे कि एक वार्बिनरी के लिए कास्टिंग:

SELECT * FROM myTable 
WHERE convert(varbinary, myField) = convert(varbinary, 'sOmeVal')

3
हालांकि यह कार्यात्मक है, यह एक उचित दृष्टिकोण नहीं है। सॉर्टिंग और स्ट्रिंग तुलना के प्रबंधन के लिए कोलाज हैं।
एडम रॉबिन्सन

@AdamRobinson हालांकि "स्ट्रिंग तुलना" के बारे में यह नहीं है?
Fandango68

@ Fandango68 हाँ, यह है, और एडम कह रहा है कि स्ट्रिंग तुलना करते समय टकराव बेहतर होते हैं।
JLRishe

@ Fandango68 यह जवाब कई स्तरों पर गलत है। कृपया विवरण के लिए मेरा उत्तर देखें, विशेष रूप से बिंदु 5.
सोलोमन रटज़की

@AdamRobinson कृपया स्ट्रिंग तुलना पर स्पष्टीकरण के लिए मेरा जवाब देखें ।
सोलोमन रटज़की

2

आप किस डेटाबेस पर हैं? MS SQL सर्वर के साथ, यह एक डेटाबेस-वाइड सेटिंग है, या आप इसे COLLATE कीवर्ड के साथ प्रति-क्वेरी कर सकते हैं।


नमस्ते। SQL सर्वर के लिए, यह प्रश्न क्या है, इसके संदर्भ में, यह न तो एक डेटाबेस-वाइड सेटिंग है और न ही प्रति-क्वेरी है। कृपया विवरण के लिए मेरा उत्तर देखें।
सोलोमन रटज़की
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.