এসকিউএল সার্ভার যেখানে অভিব্যক্তি ক্ষেত্রে ক্ষেত্রে উপেক্ষা করে


91

আমি কীভাবে একটি এসকিউএল কোয়েরি (এমএস এসকিউএল সার্ভার) তৈরি করব যেখানে "যেখানে" ধারাটি সংবেদনশীল নয়?

SELECT * FROM myTable WHERE myField = 'sOmeVal'

আমি মামলাটি উপেক্ষা করে ফলাফল ফিরে আসতে চাই

উত্তর:


137

একটি SQL সার্ভার ডাটাবেস ডিফল্ট কনফিগারেশনে, স্ট্রিং তুলনা হয় কেস-অবশ। যদি আপনার ডাটাবেস এই সেটিংটিকে (বিকল্প কোলেশন ব্যবহারের মাধ্যমে) ওভাররাইড করে, তবে আপনার কোয়েরিতে কোন ধরণের কোলেশন ব্যবহার করতে হবে তা আপনাকে নির্দিষ্ট করতে হবে।

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

মনে রাখবেন যে আমি সরবরাহ করেছিলাম তা কেবল একটি উদাহরণ (যদিও এটি সম্ভবত আপনার পক্ষে খুব ভাল কাজ করবে)। এসকিউএল সার্ভারের কোলিশনের আরও পুঙ্খানুপুঙ্খ রূপরেখা এখানে পাওয়া যাবে


কেবলমাত্র নিশ্চিত করার জন্য, এটিকে কেবল WHEREবিবৃতি শেষে একবার যুক্ত করা দরকার , এবং সমস্ত WHEREধারাটি প্রভাবিত করবে , তাই না?
ashleedawg

জানতে চান আপনার উত্তরটিতে কোনও কলাম মানকে UPPERবা LOWERকেসে রূপান্তর করে LIKEঅনুসন্ধানটি ব্যবহার করে কোনও পারফরম্যান্স সমস্যা আছে?
শাইজু টি

4
@ অ্যাশলিডগ - ভাল প্রশ্ন .. এটি প্রতি-লাইন সেটিংস বলে মনে হচ্ছে।
লিও গুরুদিয়ান

30

সাধারণত, স্ট্রিং তুলনাগুলি কেস-সংবেদনশীল হয়। যদি আপনার ডাটাবেস সংবেদনশীল কোলেশন জন্য কনফিগার করা আছে, আপনি একটি কেস সংবেদনশীল ব্যবহার করতে বাধ্য করতে হবে:

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

@ এসকেবি। এবং আন্দ্রেজ: এটি প্রযুক্তিগতভাবে কোনও ডাটাবেস কনফিগারেশন সমস্যা নয়। স্ট্রিং তুলনা স্পষ্ট করার জন্য দয়া করে আমার উত্তর দেখুন ।
সলোমন রুটজকি 31'19

21

আমি অন্য কোথাও একটি সমাধান খুঁজে পেয়েছি; যে, ব্যবহার

upper(@yourString)

তবে এখানকার প্রত্যেকেই বলছেন যে এসকিউএল সার্ভারে এটি কোনওভাবেই কেস উপেক্ষা করার কারণে কিছু যায় আসে না? আমি নিশ্চিত যে আমাদের ডাটাবেসটি কেস-সংবেদনশীল।


7
আপনি সঠিক যে কোনও ডাটাবেস কেস কে সংবেদনশীল করে তোলা যেতে পারে তবে এটি প্রয়োজন সত্ত্বেও এটি বেশ অদক্ষ। COLLATE হ'ল কীওয়ার্ড।
mjaggard

4
এটি আনার জন্য ধন্যবাদ, @ এমজেগার্ড। আমি আশা করি আপনি বা যে কেউ আমার উত্তরটিকে নীচে নামাচ্ছে বলে মনে করেন, নিজের মতো যে কেউ আমার মত উত্তর অনুসন্ধান করেন এবং খুঁজে পান তার ভালোর জন্য বিস্তারিত বর্ণনা করুন।
ড্যানি

4
এটি উত্সাহযুক্ত কারণ এটি নিখুঁত যুক্তিযুক্ত ব্যাখ্যা। কোলেট খুব বেশি ওভারহেডের স্ম্যাক করে এবং যদি আপনার স্ট্রিংয়ে এমন অক্ষর থাকে যা কোলেশন বুঝতে পারে না? ল্যাটিন 1 একটি লসী এনকোডিং স্কিম। আপনার স্ট্রিংটিতে অ্যাড্রোপ্ফ থাকলে (যেমন: ও'ব্রায়েন) অর্থপূর্ণ ফলাফল পাওয়ার জন্য সৌভাগ্য।
বেগুন

4
পাশাপাশি উত্সাহিত। আমি প্রচুর ক্ষেত্রে চিন্তা করতে পারি যেখানে এটি কার্যকর হবে। অতিরিক্তভাবে, কিছু করার জন্য একাধিক ভাল উপায় রয়েছে।
ইনভারসাস

4
তুলনার উদ্দেশ্যে স্ট্রিংয়ের ক্ষেত্রে পরিবর্তন করা সাধারণত খারাপ। কিছু ভাষায় রূপান্তরগুলি রাউন্ড ট্রিপ করে না। যেমন LOWER (x)! = LOWER (UPPER (x))।
সিসিস

17

শীর্ষ 2 উত্তর ( অ্যাডাম রবিনসন এবং আন্দ্রেজ ক্যানিকোভস থেকে ) দয়াবান , বাছাই করা সঠিক, যাতে তারা প্রযুক্তিগতভাবে কাজ করে তবে তাদের ব্যাখ্যাগুলি ভুল এবং তাই অনেক ক্ষেত্রে বিভ্রান্তিকর হতে পারে। উদাহরণস্বরূপ, SQL_Latin1_General_CP1_CI_ASকোলেশন অনেক ক্ষেত্রে কাজ করবে, তবে এটি উপযুক্ত কেস-সংবেদনশীল কোলেশন হিসাবে ধরে নেওয়া উচিত নয়। আসলে, ওপিতে একটি কেস-সংবেদনশীল (বা সম্ভবত বাইনারি) কোলেশন সহ একটি ডেটাবেজে কাজ করছে তা আমরা জেনেছি যে ওপি এত সংখ্যক ইনস্টলেশনের জন্য ডিফল্ট যে কোলেশনটি ব্যবহার করছে না (বিশেষত কোনও ওএসে ইনস্টল থাকা কোনও) ব্যবহার ভাষা হিসেবে US English ব্যবহার): SQL_Latin1_General_CP1_CI_AS। অবশ্যই, ওপি ব্যবহার করতে পারে SQL_Latin1_General_CP1_CS_AS, কিন্তু যখন কাজ করেVARCHARডেটা, কোড পৃষ্ঠা পরিবর্তন না করা গুরুত্বপূর্ণ কারণ এটি ডেটা ক্ষতি হতে পারে এবং এটি কোলেশনের স্থানীয় / সংস্কৃতি দ্বারা নিয়ন্ত্রিত হয় (যেমন লাতিন 1_ জেনারেল বনাম ফরাসি বনাম হিব্রু ইত্যাদি)। নীচের পয়েন্ট # 9 দেখুন।

অন্য চারটি উত্তর ভিন্ন ভিন্ন ডিগ্রির ভুল।

আমি এখানে সমস্ত ভুল বোঝাবুঝি পরিষ্কার করব যাতে পাঠকরা আশা করি সবচেয়ে উপযুক্ত / দক্ষ পছন্দ করতে পারেন।

  1. ব্যবহার করবেন না UPPER()। এটি সম্পূর্ণ অপ্রয়োজনীয় অতিরিক্ত কাজ। একটি COLLATEধারা ব্যবহার করুন । উভয় ক্ষেত্রে একটি স্ট্রিং তুলনা করা দরকার, তবে UPPER()একটি উচ্চতর ক্ষেত্রে ম্যাপিং রয়েছে কিনা তা দেখার জন্য অক্ষর অনুসারে অক্ষরটি পরীক্ষা করে দেখতে হবে এবং তারপরে এটি পরিবর্তন করতে হবে। এবং আপনার উভয় পক্ষেই এটি করা দরকার। যুক্ত করা COLLATEসহজভাবে প্রক্রিয়াকরণটিকে ডিফল্টরূপে চলে যাওয়ার চেয়ে বিধিগুলির বিভিন্ন সেট ব্যবহার করে উত্পন্ন করার নির্দেশ দেয়। ব্যবহারটি COLLATEস্পষ্টতই আরও দক্ষ (বা "পারফরম্যান্ট"), যদি আপনি এই শব্দটি পছন্দ করেন :) ব্যবহার করার চেয়ে UPPER(), এই পরীক্ষার স্ক্রিপ্টে প্রমাণিত (পেস্টবিনে)

    এছাড়া ইস্যু উপর @ ড্যানি এর উত্তর @Ceisc দ্বারা লক্ষনীয়:

    কিছু ভাষায় রূপান্তরগুলি রাউন্ড ট্রিপ করে না। যেমন LOWER (x)! = LOWER (UPPER (x))।

    তুর্কি আপার কেস "İ" এর সাধারণ উদাহরণ।

  2. না, কোলেশন কোনও ডাটাবেস-বিস্তৃত সেটিং নয়, অন্তত এই প্রসঙ্গে নয়। একটি ডাটাবেস-স্তরের ডিফল্ট কল্যানেশন রয়েছে এবং এটি পরিবর্তিত এবং নতুন তৈরি কলামগুলির জন্য ডিফল্ট হিসাবে ব্যবহৃত হয় COLLATEযা ধারাটি নির্দিষ্ট করে না (যা সম্ভবত এই সাধারণ ভুল ধারণাটি এসেছে) তবে এটি সরাসরি প্রশ্নের উপর প্রভাব ফেলে না যদি আপনি না হন স্ট্রিং লিটারাল এবং ভেরিয়েবলকে অন্য স্ট্রিং লিটারেল এবং ভেরিয়েবলের সাথে তুলনা করে, বা আপনি ডাটাবেস-স্তরের মেটা-ডেটা উল্লেখ করছেন।

  3. না, কোলেশন কোয়েরি অনুসারে নয়।

  4. কোলেশনগুলি প্রিডিকেট (অর্থাত্ কিছু কিছু অপ্রেন্ড কিছু) বা অভিব্যক্তি, প্রতি প্রশ্নের জন্য নয়। এবং এটি পুরো ক্লোয়ারের জন্য সত্য, কেবল WHEREধারা নয়। এটি জয়েন্টস, বাই গ্রুপ, অর্ডার বাই, পার্টিশন বাই ইত্যাদি কভার করে

  5. না, নিম্নলিখিত কারণে VARBINARY(যেমন convert(varbinary, myField) = convert(varbinary, 'sOmeVal')) রূপান্তর করবেন না :

    1. এটি একটি বাইনারি তুলনা, যা কেস-সংবেদনশীল নয় (যা এই প্রশ্নটি জিজ্ঞাসা করছে)
    2. আপনি যদি বাইনারি তুলনা করতে চান তবে একটি বাইনারি কোলেশন ব্যবহার করুন। _BIN2যদি আপনি এসকিউএল সার্ভার ব্যবহার করেন 2008 বা আরও নতুন ব্যবহার করা হয় তবে এটির সাথে একটিটি ব্যবহার করুন, অন্যথায় আপনার সাথে শেষ হওয়া কোনওটি ব্যবহার করার বিকল্প নেই _BIN। তথ্য থাকলে NVARCHARতারপর এটা কোন ব্যাপার না, যা লোকেল আপনি ব্যবহার হিসাবে তারা যে সব ক্ষেত্রে একই রকম, অত: পর Latin1_General_100_BIN2সবসময় কাজ করে। তথ্য থাকলে VARCHAR, আপনি একই লোকেল ব্যবহার করা আবশ্যক যে ডেটা (যেমন বর্তমানে Latin1_General, French, Japanese_XJIS, ইত্যাদি) কারণ লোকেল যে ব্যবহার করা হয় কোড পৃষ্ঠা নির্ধারণ করে, এবং কোড পৃষ্ঠাগুলি পরিবর্তন তথ্য (অর্থাত ডেটা হারিয়ে) পরিবর্তন করতে পারেন।
    3. আকার নির্দিষ্ট না করে একটি ভেরিয়েবল-দৈর্ঘ্যের ডেটাটাইপ ব্যবহার করা ডিফল্ট আকারের উপর নির্ভর করবে এবং যেখানে ডেটাটাইপ ব্যবহৃত হচ্ছে সেই প্রসঙ্গে দুটি ভিন্ন ডিফল্ট রয়েছে। এটি স্ট্রিং ধরণের জন্য 1 বা 30 হয়। CONVERT()এটির সাথে ব্যবহার করার সময় 30 টি ডিফল্ট মান ব্যবহার করবে। বিপদটি হ'ল, যদি স্ট্রিংটি 30 বাইটের বেশি হতে পারে তবে এটি নিঃশব্দে কেটে যাবে এবং আপনি সম্ভবত এই প্রাকটিক্ট থেকে ভুল ফলাফল পাবেন।
    4. এমনকি আপনি যদি কেস সংবেদনশীল তুলনা চাই, বাইনারি collations হয় না কেস সংবেদনশীল (অন্য খুব সাধারণ ভুল ধারণা)।
  6. না, LIKEসবসময় ক্ষেত্রে সংবেদনশীল হয় না। এটি রেফারেন্সযুক্ত কলামের কোলেশন বা ডাটাবেসটির কোলেশন ব্যবহার করে যদি কোনও ভেরিয়েবলকে একটি স্ট্রিং আক্ষরিকের সাথে তুলনা করা হয়, বা alচ্ছিক COLLATEঅনুচ্ছেদের মাধ্যমে নির্দিষ্ট কোলাশ ব্যবহার করা হয় ।

  7. LCASEকোনও এসকিউএল সার্ভার ফাংশন নয়। এটি ওরাকল বা মাইএসকিউএল বলে মনে হচ্ছে। অথবা সম্ভবত ভিজ্যুয়াল বেসিক?

  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[_]%';
    

কোলেশন, এনকোডিং ইত্যাদির আরও তথ্যের জন্য দয়া করে এখানে যান: কোলেশন তথ্য


7

না, কেবলমাত্র ব্যবহার করা কার্যকর LIKEহবে না। LIKEআপনার প্রদত্ত প্যাটার্নের সাথে মিল খুঁজে পাওয়া মানগুলি সন্ধান করে। এই ক্ষেত্রে LIKEশুধুমাত্র টেক্সট 'sOmeVal' এবং 'someval' খুঁজতে হবে।

একটি অন্বেষণযোগ্য সমাধানটি LCASE()ফাংশনটি ব্যবহার করছে । LCASE('sOmeVal')আপনার পাঠ্যের ছোট হাতের স্ট্রিং পান: 'কিছুকাল'। আপনি যদি এই তুলনাটির উভয় পক্ষের জন্য এই ফাংশনটি ব্যবহার করেন তবে এটি কাজ করে:

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

বিবৃতিটি দুটি ছোট হাতের স্ট্রিংকে তুলনা করে, যাতে আপনার 'সোমওয়াল' 'কিছু কিছু' (যেমন 'সামোভাল', 'সোমোভেল' ইত্যাদি) এর প্রতিটি স্বরলিপি মিলবে।


7
_CI জমে থাকা এসকিউএল সার্ভার ইনস্টলেশনগুলির 99.9%-তে, লাইক কেস সংবেদনশীল।
রিচার্ডকিউই

4
আজকাল ফাংশনটিকে
ডেভিড ব্রসার্ড

@ ডেভিডব্রসার্ড এবং ডেভিড হারম্যানস, আমি মনে করি না যে এটি কখনও LCASE()এসকিউএল সার্ভারে ছিল (অন্তত আমি দেখতে পাচ্ছি না)। আমি মনে করি এই উত্তরটি সম্পূর্ণ ভিন্ন আরডিবিএমএসের জন্য। স্ট্রিং তুলনা স্পষ্ট করার জন্য দয়া করে আমার উত্তর দেখুন ।
সলোমন রুটজকি 31'19

4

আপনি কেসটিকে সংবেদনশীল করতে বাধ্য করতে পারেন, তার মতো ভেরিবিনারে castালাই:

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

4
যদিও এটি কার্যকরী, এটি কোনও পরামর্শমূলক পদ্ধতির নয়। বাছাই এবং স্ট্রিং তুলনা পরিচালনা পরিচালনার জন্য কলেশন রয়েছে।
অ্যাডাম রবিনসন

@ অ্যাডামরবিনসন যদিও এটি "স্ট্রিং তুলনা" সম্পর্কে নয়?
Fandango68

@ ফানডাঙ্গো Yes৮ হ্যাঁ, এটি হ'ল এবং অ্যাডাম বলছেন যে স্ট্রিং তুলনা করার সময় কোলেশনগুলি আরও ভাল।
JLRishe

@ ফানডাঙ্গো 68 এই উত্তরটি বিভিন্ন স্তরে ভুল। দয়া করে দেখুন আমার উত্তর বিস্তারিত জানার জন্য, বিশেষ করে বাতলান 5.
সলোমন Rutzky

@ অ্যাডামরবিনসন দয়া করে স্ট্রিং তুলনা সম্পর্কে স্পষ্টতার জন্য আমার উত্তর দেখুন ।
সলোমন রুটজকি

2

আপনি কোন ডাটাবেসে আছেন? এমএস এসকিউএল সার্ভারের সাহায্যে এটি একটি ডাটাবেস-বিস্তৃত সেটিংস, অথবা আপনি এটি কোল্যাট কীওয়ার্ড সহ প্রতি-কোয়েরিতে অতিরিক্ত চালাতে পারেন।


হাই! এসকিউএল সার্ভারের ক্ষেত্রে, এই প্রশ্নটি কীসের দিক থেকে এটি কোনও ডাটাবেস-বিস্তৃত সেটিংস বা প্রতি-কোয়েরি নয়। দয়া করে দেখুন আমার উত্তর বিস্তারিত জানার জন্য।
সলোমন রুটজকি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.