मैं एक SQL क्वेरी (MS SQL सर्वर) का निर्माण कैसे करता हूं, जहां "जहां" खंड केस-असंवेदनशील है?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
मैं चाहता हूं कि परिणाम मामले की अनदेखी करके वापस आएं
मैं एक SQL क्वेरी (MS SQL सर्वर) का निर्माण कैसे करता हूं, जहां "जहां" खंड केस-असंवेदनशील है?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
मैं चाहता हूं कि परिणाम मामले की अनदेखी करके वापस आएं
जवाबों:
एक SQL सर्वर डेटाबेस का डिफ़ॉल्ट विन्यास में, स्ट्रिंग तुलना कर रहे हैं केस-संवेदी। यदि आपका डेटाबेस इस सेटिंग (एक वैकल्पिक टकराव के उपयोग के माध्यम से) को ओवरराइड करता है, तो आपको यह निर्दिष्ट करने की आवश्यकता होगी कि आपकी क्वेरी में किस प्रकार के कोलाज का उपयोग करना है।
SELECT * FROM myTable WHERE myField = 'sOmeVal' COLLATE SQL_Latin1_General_CP1_CI_AS
ध्यान दें कि मेरे द्वारा प्रदान किया गया कोलाजेशन केवल एक उदाहरण है (हालांकि यह आपके लिए संभावित फ़ंक्शन से अधिक होगा)। SQL सर्वर collations की अधिक गहन रूपरेखा यहाँ मिल सकती है ।
UPPER
या LOWER
केस में परिवर्तित करके कोई प्रदर्शन समस्या है LIKE
?
आमतौर पर, स्ट्रिंग तुलना मामले-असंवेदनशील हैं। यदि आपके डेटाबेस को संवेदनशील समतलीकरण के लिए कॉन्फ़िगर किया गया है, तो आपको असंवेदनशील एक मामले का उपयोग करने के लिए मजबूर करना होगा:
SELECT balance FROM people WHERE email = 'billg@microsoft.com'
COLLATE SQL_Latin1_General_CP1_CI_AS
मुझे एक और समाधान कहीं और मिला; वह है, उपयोग करने के लिए
upper(@yourString)
लेकिन यहां हर कोई कह रहा है कि, SQL सर्वर में, यह कोई फर्क नहीं पड़ता क्योंकि यह वैसे भी मामले की अनदेखी कर रहा है? मुझे पूरा यकीन है कि हमारा डेटाबेस केस-संवेदी है।
शीर्ष 2 उत्तर ( एडम रॉबिन्सन और बेन्स कैनिकोव्स से ) थोड़े हैं, सॉर्ट सही हैं, इसमें वे तकनीकी रूप से काम करते हैं, लेकिन उनकी व्याख्या गलत है और इसलिए कई मामलों में भ्रामक हो सकती है। उदाहरण के लिए, जबकि SQL_Latin1_General_CP1_CI_AS
टकराव कई मामलों में काम करेगा, इसे उचित मामला-असंवेदनशील टकराव नहीं माना जाना चाहिए। वास्तव में, यह देखते हुए कि ओपी एक केस-संवेदी (या संभवतः बाइनरी) कॉलेशन के साथ एक डेटाबेस में काम कर रहा है, हम जानते हैं कि ओपी उस कॉलेशन का उपयोग नहीं कर रहा है जो इतने सारे इंस्टॉलेशन के लिए डिफ़ॉल्ट है (विशेष रूप से किसी ओएस पर स्थापित) भाषा के रूप में यूएस अंग्रेजी का उपयोग करना) SQL_Latin1_General_CP1_CI_AS
:। बेशक, ओपी का उपयोग किया जा सकता है SQL_Latin1_General_CP1_CS_AS
, लेकिन जब साथ काम कर रहा हैVARCHAR
डेटा, कोड पृष्ठ को नहीं बदलना महत्वपूर्ण है क्योंकि यह डेटा हानि का कारण बन सकता है, और इसे नियंत्रण के स्थानीय / संस्कृति द्वारा नियंत्रित किया जाता है (यानी लैटिन 1_General बनाम फ्रेंच बनाम हिब्रू आदि)। कृपया नीचे बिंदु # 9 देखें।
अन्य चार उत्तर अलग-अलग डिग्री के लिए गलत हैं।
मैं यहां सभी गलतफहमी को स्पष्ट कर दूंगा ताकि पाठक सबसे उपयुक्त / कुशल विकल्प चुन सकें।
उपयोग न करें UPPER()
। यह पूरी तरह से अनावश्यक अतिरिक्त काम है। एक COLLATE
क्लॉज का उपयोग करें । एक स्ट्रिंग तुलना को किसी भी मामले में किए जाने की आवश्यकता होती है, लेकिन UPPER()
यह भी देखने के लिए कि चरित्र द्वारा चरित्र की जांच करना है, यह देखने के लिए कि क्या कोई ऊपरी-मामला मानचित्रण है, और फिर इसे बदल दें। और आपको दोनों तरफ ऐसा करने की आवश्यकता है। जोड़ा जा रहा है COLLATE
बस नियमों का एक अलग सेट की तुलना में यह डिफ़ॉल्ट रूप से जा रहा था का उपयोग कर तरह कुंजी उत्पन्न करने के लिए प्रसंस्करण निर्देश देता है। का उपयोग करना COLLATE
निश्चित रूप से अधिक कुशल है (या " परफ़ॉर्मेंट ", यदि आपको वह शब्द पसंद है :) का उपयोग करने की तुलना में UPPER()
, जैसा कि इस परीक्षण स्क्रिप्ट में साबित किया गया है (पेस्टबिन पर) ।
@ डैनी के उत्तर पर @Ceisc द्वारा नोट किया गया मुद्दा भी है :
कुछ भाषाओं के मामले में रूपांतरण गोल-यात्रा नहीं करते हैं। यानी LOWER (x)! = LOWER (UPPER (x))।
तुर्की ऊपरी मामला "İ" सामान्य उदाहरण है।
नहीं, टकराव एक डेटाबेस-वाइड सेटिंग नहीं है, कम से कम इस संदर्भ में नहीं। एक डेटाबेस-लेवल डिफ़ॉल्ट कॉलेशन है, और इसका उपयोग परिवर्तित और नए बनाए गए स्तंभों के लिए डिफ़ॉल्ट के रूप में किया जाता है COLLATE
जो क्लॉज़ को निर्दिष्ट नहीं करते हैं (जो संभवतः यह सामान्य गलत धारणा है), लेकिन यह सीधे प्रश्नों पर प्रभाव नहीं डालता है जब तक आप नहीं हैं स्ट्रिंग स्ट्रिंग और वेरिएबल्स की तुलना अन्य स्ट्रिंग लिटरल और वैरिएबल्स या आप डेटाबेस-स्तर मेटा-डेटा के संदर्भ में कर रहे हैं।
नहीं, टक्कर प्रति प्रश्न नहीं है।
कोलायत विधेय के अनुसार प्रतिगामी (यानी कुछ परिचालित कुछ) या अभिव्यक्ति हैं। और यह पूरे क्वेरी के लिए सही है, न कि केवल WHERE
क्लॉज के लिए। इसमें JOINs, GROUP BY, ORDER BY, पार्टीशन BY आदि शामिल हैं।
नहीं, निम्न कारणों से VARBINARY
(जैसे convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
) में परिवर्तित न करें :
_BIN2
यदि आप SQL Server 2008 या नए का उपयोग कर रहे हैं, तो एक का उपयोग करें , अन्यथा आपके पास समाप्त होने वाले एक का उपयोग करने के अलावा कोई विकल्प नहीं है _BIN
। यदि डेटा है NVARCHAR
तो इससे कोई फर्क नहीं पड़ता कि आप किस लोकेल का उपयोग करते हैं क्योंकि वे उस मामले में सभी समान हैं, इसलिए Latin1_General_100_BIN2
हमेशा काम करता है। डेटा है VARCHAR
, आप एक ही स्थान का उपयोग करना चाहिए कि डेटा (जैसे में है Latin1_General
, French
, Japanese_XJIS
, आदि) क्योंकि वातावरण है कि प्रयोग किया जाता है कोड पेज को निर्धारित करता है, और कोड पृष्ठों को बदलने डेटा (यानी डेटा हानि) बदल सकते हैं।CONVERT()
तो 30 डिफ़ॉल्ट मूल्य का उपयोग करेगा। खतरा यह है, अगर स्ट्रिंग 30 बाइट्स से अधिक हो सकती है, तो यह चुपचाप काट दिया जाएगा और आपको संभवतः इस विधेय से गलत परिणाम मिलेंगे।नहीं, LIKE
हमेशा केस-संवेदी नहीं होता है। यह संदर्भित किए जा रहे कॉलम के कोलाजेशन का उपयोग करता है, या डेटाबेस का टकराव अगर किसी स्ट्रिंग शाब्दिक, या वैकल्पिक COLLATE
क्लॉज के माध्यम से निर्दिष्ट कोलाज की तुलना करता है ।
LCASE
SQL सर्वर फ़ंक्शन नहीं है। यह Oracle या MySQL प्रतीत होता है। या संभवतः विजुअल बेसिक?
चूँकि प्रश्न का संदर्भ किसी स्तंभ को स्ट्रिंग शाब्दिक से तुलना कर रहा है, न तो उदाहरण का टकराव (अक्सर "सर्वर" के रूप में जाना जाता है) और न ही डेटाबेस के टकराव का यहां कोई सीधा प्रभाव पड़ता है। कोलाज प्रत्येक कॉलम में संग्रहीत किए जाते हैं, और प्रत्येक कॉलम में एक अलग कोलाजेशन हो सकता है, और उन कोलाज को डेटाबेस के डिफ़ॉल्ट कोलाजेशन या इंस्टेंस के कोलाजेशन के समान होने की आवश्यकता नहीं होती है। निश्चित रूप से, उदाहरण कोलाजेशन एक नए बनाए गए डेटाबेस के लिए डिफ़ॉल्ट है जो डेटाबेस COLLATE
बनाते समय यदि क्लॉज निर्दिष्ट नहीं किया गया था , तो यह उसके डिफ़ॉल्ट टकराव के रूप में उपयोग करेगा । और इसी तरह, डेटाबेस का डिफॉल्ट कॉलेशन वह है जो परिवर्तित या नए बनाए गए कॉलम का उपयोग करेगा यदि COLLATE
क्लॉज निर्दिष्ट नहीं किया गया था।
आपको केस-असंवेदनशील कोलाजेशन का उपयोग करना चाहिए जो अन्यथा स्तंभ के टकराव के समान है। स्तंभ के टकराने (तालिका का नाम और स्कीमा नाम बदलें) को खोजने के लिए निम्नलिखित क्वेरी का उपयोग करें:
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
नहीं, केवल उपयोग करने LIKE
से काम नहीं चलेगा। LIKE
आपके दिए गए पैटर्न से मिलते-जुलते मूल्य खोजता है। इस मामले में LIKE
केवल पाठ 'sOmeVal' और 'कुछ' नहीं मिलेगा।
एक pracitcable समाधान LCASE()
फ़ंक्शन का उपयोग कर रहा है। LCASE('sOmeVal')
आपके पाठ का निचला भाग मिलता है: 'कुछ'। यदि आप अपनी तुलना के दोनों ओर इस फ़ंक्शन का उपयोग करते हैं, तो यह काम करता है:
SELECT * FROM myTable WHERE LCASE(myField) LIKE LCASE('sOmeVal')
बयान दो लोअरकेस स्ट्रिंग्स की तुलना करता है, ताकि आपका 'सॉमेवैल' 'कुछ' (जैसे 'कुछ', 'कुछ' इत्यादि) के हर दूसरे अंकन से मेल खाए।
LCASE()
एसक्यूएल सर्वर में कभी था (कम से कम ऐसा नहीं जिसे मैं देख सकता हूं)। मुझे लगता है कि यह उत्तर पूरी तरह से अलग RDBMS के लिए है। कृपया स्ट्रिंग तुलना पर स्पष्टीकरण के लिए मेरा जवाब देखें ।
आप केस को संवेदनशील बनाने के लिए बाध्य कर सकते हैं, जैसे कि एक वार्बिनरी के लिए कास्टिंग:
SELECT * FROM myTable
WHERE convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
आप किस डेटाबेस पर हैं? MS SQL सर्वर के साथ, यह एक डेटाबेस-वाइड सेटिंग है, या आप इसे COLLATE कीवर्ड के साथ प्रति-क्वेरी कर सकते हैं।
WHERE
बयान के अंत में एक बार जोड़ा जाना चाहिए , और सभीWHERE
खंडों को प्रभावित करेगा , सही?