আমি কীভাবে একটি এসকিউএল কোয়েরি (এমএস এসকিউএল সার্ভার) তৈরি করব যেখানে "যেখানে" ধারাটি সংবেদনশীল নয়?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
আমি মামলাটি উপেক্ষা করে ফলাফল ফিরে আসতে চাই
আমি কীভাবে একটি এসকিউএল কোয়েরি (এমএস এসকিউএল সার্ভার) তৈরি করব যেখানে "যেখানে" ধারাটি সংবেদনশীল নয়?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
আমি মামলাটি উপেক্ষা করে ফলাফল ফিরে আসতে চাই
উত্তর:
একটি SQL সার্ভার ডাটাবেস ডিফল্ট কনফিগারেশনে, স্ট্রিং তুলনা হয় কেস-অবশ। যদি আপনার ডাটাবেস এই সেটিংটিকে (বিকল্প কোলেশন ব্যবহারের মাধ্যমে) ওভাররাইড করে, তবে আপনার কোয়েরিতে কোন ধরণের কোলেশন ব্যবহার করতে হবে তা আপনাকে নির্দিষ্ট করতে হবে।
SELECT * FROM myTable WHERE myField = 'sOmeVal' COLLATE SQL_Latin1_General_CP1_CI_AS
মনে রাখবেন যে আমি সরবরাহ করেছিলাম তা কেবল একটি উদাহরণ (যদিও এটি সম্ভবত আপনার পক্ষে খুব ভাল কাজ করবে)। এসকিউএল সার্ভারের কোলিশনের আরও পুঙ্খানুপুঙ্খ রূপরেখা এখানে পাওয়া যাবে ।
UPPER
বা LOWER
কেসে রূপান্তর করে LIKE
অনুসন্ধানটি ব্যবহার করে কোনও পারফরম্যান্স সমস্যা আছে?
সাধারণত, স্ট্রিং তুলনাগুলি কেস-সংবেদনশীল হয়। যদি আপনার ডাটাবেস সংবেদনশীল কোলেশন জন্য কনফিগার করা আছে, আপনি একটি কেস সংবেদনশীল ব্যবহার করতে বাধ্য করতে হবে:
SELECT balance FROM people WHERE email = 'billg@microsoft.com'
COLLATE SQL_Latin1_General_CP1_CI_AS
আমি অন্য কোথাও একটি সমাধান খুঁজে পেয়েছি; যে, ব্যবহার
upper(@yourString)
তবে এখানকার প্রত্যেকেই বলছেন যে এসকিউএল সার্ভারে এটি কোনওভাবেই কেস উপেক্ষা করার কারণে কিছু যায় আসে না? আমি নিশ্চিত যে আমাদের ডাটাবেসটি কেস-সংবেদনশীল।
শীর্ষ 2 উত্তর ( অ্যাডাম রবিনসন এবং আন্দ্রেজ ক্যানিকোভস থেকে ) দয়াবান , বাছাই করা সঠিক, যাতে তারা প্রযুক্তিগতভাবে কাজ করে তবে তাদের ব্যাখ্যাগুলি ভুল এবং তাই অনেক ক্ষেত্রে বিভ্রান্তিকর হতে পারে। উদাহরণস্বরূপ, SQL_Latin1_General_CP1_CI_AS
কোলেশন অনেক ক্ষেত্রে কাজ করবে, তবে এটি উপযুক্ত কেস-সংবেদনশীল কোলেশন হিসাবে ধরে নেওয়া উচিত নয়। আসলে, ওপিতে একটি কেস-সংবেদনশীল (বা সম্ভবত বাইনারি) কোলেশন সহ একটি ডেটাবেজে কাজ করছে তা আমরা জেনেছি যে ওপি এত সংখ্যক ইনস্টলেশনের জন্য ডিফল্ট যে কোলেশনটি ব্যবহার করছে না (বিশেষত কোনও ওএসে ইনস্টল থাকা কোনও) ব্যবহার ভাষা হিসেবে US English ব্যবহার): SQL_Latin1_General_CP1_CI_AS
। অবশ্যই, ওপি ব্যবহার করতে পারে SQL_Latin1_General_CP1_CS_AS
, কিন্তু যখন কাজ করেVARCHAR
ডেটা, কোড পৃষ্ঠা পরিবর্তন না করা গুরুত্বপূর্ণ কারণ এটি ডেটা ক্ষতি হতে পারে এবং এটি কোলেশনের স্থানীয় / সংস্কৃতি দ্বারা নিয়ন্ত্রিত হয় (যেমন লাতিন 1_ জেনারেল বনাম ফরাসি বনাম হিব্রু ইত্যাদি)। নীচের পয়েন্ট # 9 দেখুন।
অন্য চারটি উত্তর ভিন্ন ভিন্ন ডিগ্রির ভুল।
আমি এখানে সমস্ত ভুল বোঝাবুঝি পরিষ্কার করব যাতে পাঠকরা আশা করি সবচেয়ে উপযুক্ত / দক্ষ পছন্দ করতে পারেন।
ব্যবহার করবেন না UPPER()
। এটি সম্পূর্ণ অপ্রয়োজনীয় অতিরিক্ত কাজ। একটি COLLATE
ধারা ব্যবহার করুন । উভয় ক্ষেত্রে একটি স্ট্রিং তুলনা করা দরকার, তবে UPPER()
একটি উচ্চতর ক্ষেত্রে ম্যাপিং রয়েছে কিনা তা দেখার জন্য অক্ষর অনুসারে অক্ষরটি পরীক্ষা করে দেখতে হবে এবং তারপরে এটি পরিবর্তন করতে হবে। এবং আপনার উভয় পক্ষেই এটি করা দরকার। যুক্ত করা COLLATE
সহজভাবে প্রক্রিয়াকরণটিকে ডিফল্টরূপে চলে যাওয়ার চেয়ে বিধিগুলির বিভিন্ন সেট ব্যবহার করে উত্পন্ন করার নির্দেশ দেয়। ব্যবহারটি COLLATE
স্পষ্টতই আরও দক্ষ (বা "পারফরম্যান্ট"), যদি আপনি এই শব্দটি পছন্দ করেন :) ব্যবহার করার চেয়ে UPPER()
, এই পরীক্ষার স্ক্রিপ্টে প্রমাণিত (পেস্টবিনে) ।
এছাড়া ইস্যু উপর @ ড্যানি এর উত্তর @Ceisc দ্বারা লক্ষনীয়:
কিছু ভাষায় রূপান্তরগুলি রাউন্ড ট্রিপ করে না। যেমন LOWER (x)! = LOWER (UPPER (x))।
তুর্কি আপার কেস "İ" এর সাধারণ উদাহরণ।
না, কোলেশন কোনও ডাটাবেস-বিস্তৃত সেটিং নয়, অন্তত এই প্রসঙ্গে নয়। একটি ডাটাবেস-স্তরের ডিফল্ট কল্যানেশন রয়েছে এবং এটি পরিবর্তিত এবং নতুন তৈরি কলামগুলির জন্য ডিফল্ট হিসাবে ব্যবহৃত হয় COLLATE
যা ধারাটি নির্দিষ্ট করে না (যা সম্ভবত এই সাধারণ ভুল ধারণাটি এসেছে) তবে এটি সরাসরি প্রশ্নের উপর প্রভাব ফেলে না যদি আপনি না হন স্ট্রিং লিটারাল এবং ভেরিয়েবলকে অন্য স্ট্রিং লিটারেল এবং ভেরিয়েবলের সাথে তুলনা করে, বা আপনি ডাটাবেস-স্তরের মেটা-ডেটা উল্লেখ করছেন।
না, কোলেশন কোয়েরি অনুসারে নয়।
কোলেশনগুলি প্রিডিকেট (অর্থাত্ কিছু কিছু অপ্রেন্ড কিছু) বা অভিব্যক্তি, প্রতি প্রশ্নের জন্য নয়। এবং এটি পুরো ক্লোয়ারের জন্য সত্য, কেবল WHERE
ধারা নয়। এটি জয়েন্টস, বাই গ্রুপ, অর্ডার বাই, পার্টিশন বাই ইত্যাদি কভার করে
না, নিম্নলিখিত কারণে VARBINARY
(যেমন convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
) রূপান্তর করবেন না :
_BIN2
যদি আপনি এসকিউএল সার্ভার ব্যবহার করেন 2008 বা আরও নতুন ব্যবহার করা হয় তবে এটির সাথে একটিটি ব্যবহার করুন, অন্যথায় আপনার সাথে শেষ হওয়া কোনওটি ব্যবহার করার বিকল্প নেই _BIN
। তথ্য থাকলে NVARCHAR
তারপর এটা কোন ব্যাপার না, যা লোকেল আপনি ব্যবহার হিসাবে তারা যে সব ক্ষেত্রে একই রকম, অত: পর Latin1_General_100_BIN2
সবসময় কাজ করে। তথ্য থাকলে VARCHAR
, আপনি একই লোকেল ব্যবহার করা আবশ্যক যে ডেটা (যেমন বর্তমানে Latin1_General
, French
, Japanese_XJIS
, ইত্যাদি) কারণ লোকেল যে ব্যবহার করা হয় কোড পৃষ্ঠা নির্ধারণ করে, এবং কোড পৃষ্ঠাগুলি পরিবর্তন তথ্য (অর্থাত ডেটা হারিয়ে) পরিবর্তন করতে পারেন।CONVERT()
এটির সাথে ব্যবহার করার সময় 30 টি ডিফল্ট মান ব্যবহার করবে। বিপদটি হ'ল, যদি স্ট্রিংটি 30 বাইটের বেশি হতে পারে তবে এটি নিঃশব্দে কেটে যাবে এবং আপনি সম্ভবত এই প্রাকটিক্ট থেকে ভুল ফলাফল পাবেন।না, LIKE
সবসময় ক্ষেত্রে সংবেদনশীল হয় না। এটি রেফারেন্সযুক্ত কলামের কোলেশন বা ডাটাবেসটির কোলেশন ব্যবহার করে যদি কোনও ভেরিয়েবলকে একটি স্ট্রিং আক্ষরিকের সাথে তুলনা করা হয়, বা alচ্ছিক COLLATE
অনুচ্ছেদের মাধ্যমে নির্দিষ্ট কোলাশ ব্যবহার করা হয় ।
LCASE
কোনও এসকিউএল সার্ভার ফাংশন নয়। এটি ওরাকল বা মাইএসকিউএল বলে মনে হচ্ছে। অথবা সম্ভবত ভিজ্যুয়াল বেসিক?
যেহেতু প্রশ্নের প্রসঙ্গটি একটি কলামকে একটি স্ট্রিং আক্ষরিকের সাথে তুলনা করছে, উদাহরণস্বরূপের কোলিশন (প্রায়শই "সার্ভার" হিসাবে পরিচিত) বা ডাটাবেসের কোলেশনগুলির কোনও প্রত্যক্ষ প্রভাব এখানে নেই। প্রতিটি কলামে কলশনগুলি সংরক্ষণ করা হয় এবং প্রতিটি কলামে আলাদা আলাদা কোলেশন থাকতে পারে এবং সেই কলশনগুলিতে ডাটাবেসের ডিফল্ট কোলেশন বা উদাহরণস্বরূপ কোলিশের মতো হওয়ার দরকার নেই। অবশ্যই, কোনও নতুন তৈরি হওয়া ডাটাবেসটি ডিফল্ট কোলিশেশন হিসাবে ব্যবহার করবে যদি 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[_]%';
কোলেশন, এনকোডিং ইত্যাদির আরও তথ্যের জন্য দয়া করে এখানে যান: কোলেশন তথ্য
না, কেবলমাত্র ব্যবহার করা কার্যকর LIKE
হবে না। LIKE
আপনার প্রদত্ত প্যাটার্নের সাথে মিল খুঁজে পাওয়া মানগুলি সন্ধান করে। এই ক্ষেত্রে LIKE
শুধুমাত্র টেক্সট 'sOmeVal' এবং 'someval' খুঁজতে হবে।
একটি অন্বেষণযোগ্য সমাধানটি LCASE()
ফাংশনটি ব্যবহার করছে । LCASE('sOmeVal')
আপনার পাঠ্যের ছোট হাতের স্ট্রিং পান: 'কিছুকাল'। আপনি যদি এই তুলনাটির উভয় পক্ষের জন্য এই ফাংশনটি ব্যবহার করেন তবে এটি কাজ করে:
SELECT * FROM myTable WHERE LCASE(myField) LIKE LCASE('sOmeVal')
বিবৃতিটি দুটি ছোট হাতের স্ট্রিংকে তুলনা করে, যাতে আপনার 'সোমওয়াল' 'কিছু কিছু' (যেমন 'সামোভাল', 'সোমোভেল' ইত্যাদি) এর প্রতিটি স্বরলিপি মিলবে।
LCASE()
এসকিউএল সার্ভারে ছিল (অন্তত আমি দেখতে পাচ্ছি না)। আমি মনে করি এই উত্তরটি সম্পূর্ণ ভিন্ন আরডিবিএমএসের জন্য। স্ট্রিং তুলনা স্পষ্ট করার জন্য দয়া করে আমার উত্তর দেখুন ।
আপনি কেসটিকে সংবেদনশীল করতে বাধ্য করতে পারেন, তার মতো ভেরিবিনারে castালাই:
SELECT * FROM myTable
WHERE convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
আপনি কোন ডাটাবেসে আছেন? এমএস এসকিউএল সার্ভারের সাহায্যে এটি একটি ডাটাবেস-বিস্তৃত সেটিংস, অথবা আপনি এটি কোল্যাট কীওয়ার্ড সহ প্রতি-কোয়েরিতে অতিরিক্ত চালাতে পারেন।
WHERE
বিবৃতি শেষে একবার যুক্ত করা দরকার , এবং সমস্তWHERE
ধারাটি প্রভাবিত করবে , তাই না?