SQL server تجاهل القضية في حيث التعبير
-
11-07-2019 - |
سؤال
كيف يمكنني إنشاء استعلام SQL (MS SQL Server) حيث "حيث" شرط الحالة-عديم الإحساس ؟
SELECT * FROM myTable WHERE myField = 'sOmeVal'
أريد نتائج العودة تجاهل القضية
المحلول
في التكوين الافتراضي من قاعدة بيانات SQL Server ، سلسلة المقارنات هي تحسس حالة الأحرف.إذا كانت قاعدة البيانات الخاصة بك يتجاوز هذا الإعداد (من خلال استخدام بديل ترتيب), ثم سوف تحتاج إلى تحديد أي نوع من ترتيب استخدامها في الاستعلام الخاص بك.
SELECT * FROM myTable WHERE myField = 'sOmeVal' COLLATE SQL_Latin1_General_CP1_CI_AS
علما بأن ترتيب قدمت مجرد مثال (على الرغم من أنه سوف أكثر من المرجح أن تعمل على ما يرام بالنسبة لك).أكثر دقة مخطط SQL Server الترتيب يمكن العثور عليها هنا.
نصائح أخرى
وعادة، مقارنات السلسلة حساسة لحالة الأحرف. إذا تم تكوين قاعدة البيانات الخاصة بك إلى الحالة الترتيب حساسة، تحتاج إلى القوة لاستخدام قضية حساسة واحد:
SELECT balance FROM people WHERE email = 'billg@microsoft.com'
COLLATE SQL_Latin1_General_CP1_CI_AS
ولقد وجدت حلا آخر في أي مكان آخر. وهذا هو، لاستخدام
upper(@yourString)
ولكن الجميع هنا يقول أنه في SQL Server، فإنه لا يهم لأنه تجاهل القضية على أي حال؟ أنا متأكد من قاعدة البيانات الخاصة بنا لحالة الأحرف.
لا، فقط باستخدام LIKE
لا تعمل. LIKE
يبحث القيم مطابقة بالضبط النمط الخاص بك معين. في هذه الحالة LIKE
سوف تجد سوى النص "sOmeVal 'وليس' someval".
وحل pracitcable يستخدم وظيفة LCASE()
. LCASE('sOmeVal')
يحصل على سلسلة صغيرة من النص: "someval. إذا كنت تستخدم هذه الوظيفة لكلا الجانبين من المقارنة الخاصة بك، وأنها تعمل:
وSELECT * FROM myTable WHERE LCASE(myField) LIKE LCASE('sOmeVal')
والبيان يقارن سلسلتين الصغيرة، وذلك بأن ما تتمتعون به "sOmeVal" سوف تطابق كل الرموز الأخرى من "someval" (مثل "Someval '،' sOMEVAl" الخ.).
أعلى 2 إجابات (من آدم روبنسون و Andrejs Cainikovs) نوعا ما ، شيء على الصحيح ، في أنها من الناحية الفنية العمل ، ولكن تفسيرات خاطئة و لذلك يمكن أن تكون مضللة في كثير من الحالات.على سبيل المثال ، في حين أن SQL_Latin1_General_CP1_CI_AS
ترتيب العمل في كثير من الحالات, فإنه لا ينبغي أن يفترض أن يكون مناسبة تحسس حالة الأحرف الترتيب.في الواقع ، بالنظر إلى أن O. P.هو العامل في قاعدة البيانات مع تحسس حالة الأحرف (أو ربما الثنائية) جمع ، ونحن نعلم أن O. P.ليس باستخدام ترتيب هذا هو الافتراضي للعديد من المنشآت (أي خاصة مثبتة على نظام التشغيل الولايات المتحدة باستخدام اللغة الإنجليزية كلغة): SQL_Latin1_General_CP1_CI_AS
.بالتأكيد, O. P. يمكن أن تستخدم SQL_Latin1_General_CP1_CS_AS
, ولكن عند العمل مع VARCHAR
البيانات ، من المهم أن لا تغيير صفحة التعليمات البرمجية كما أنه يمكن أن يؤدي إلى فقدان البيانات و التي تسيطر عليها لغة / ثقافة جمع (أيLatin1_General vs الفرنسي vs العبرية الخ).يرجى الاطلاع على النقطة رقم 9 أدناه.
غيرها من أربع إجابات خاطئة بدرجات متفاوتة.
سوف يوضح كل شيء من سوء الفهم هنا بحيث يمكن للقراء نأمل أن تجعل أنسب / الخيارات الفعالة.
لا تستخدم
UPPER()
.التي لا لزوم لها تماما من العمل الإضافي.استخدامCOLLATE
البند.سلسلة المقارنة يجب القيام به في كلتا الحالتين ، ولكن باستخدامUPPER()
أيضا قد تحقق, حرف, لمعرفة ما إذا كان هناك العليا-حالة رسم الخرائط ، ومن ثم تغييره.و تحتاج إلى القيام بذلك على كلا الجانبين.إضافةCOLLATE
ببساطة توجه المعالجة إلى توليد نوع المفاتيح باستخدام مجموعة مختلفة من القواعد من أنه كان على وشك بشكل افتراضي.باستخدامCOLLATE
هو بالتأكيد أكثر كفاءة (أو "performant" ، إذا كنت تحب هذه الكلمة :) من استخدامUPPER()
, كما ثبت في هذا اختبار البرنامج النصي (على PasteBin).وهناك أيضا قضية لاحظ @Ceisc على @داني الجواب:
في بعض اللغات حالة التحويلات لا ذهابا وإيابا.أيأقل من(س) != أقل العلوية ((x)).
التركية upper-case "أنا" هو مثال شائع.
لا ترتيب لا على قاعدة بيانات واسعة الإعداد, على الأقل ليس في هذا السياق.هناك قاعدة بيانات على مستوى ترتيب افتراضي ، يتم استخدام الافتراضي تغيير حديثا الأعمدة التي لم تحدد
COLLATE
البند (وهو الأرجح حيث أن هذا اعتقاد خاطئ يأتي من), ولكن لا يؤثر على الاستفسارات مباشرة إلا إذا كنت مقارنة سلسلة حرفية و المتغيرات الأخرى سلسلة حرفية و المتغيرات ، أو يمكنك الرجوع إلى قاعدة بيانات على مستوى البيانات الفوقية.لا ترتيب لا في الاستعلام.
الترتيب هي في المسند (أيشيء المعامل شيء) أو التعبير ، وليس في الاستعلام.وهذا ينطبق على كامل الاستعلام ، وليس فقط
WHERE
البند.هذا يغطي ينضم إلى المجموعة من قبل النظام من قبل القسم ، إلخ.لا, لا تحويل إلى
VARBINARY
(مثلا ،convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
) للأسباب التالية:- هذا هو ثنائي المقارنة ، وهي ليست حالة الأحرف (وهو ما هو هذا السؤال يسأل)
- إذا كنت لا تريد المقارنة الثنائية, استخدام ثنائي المقدمة.استخدام واحدة أن ينتهي
_BIN2
إذا كنت تستخدم SQL Server 2008 أو أحدث, آخر لا يوجد لديك خيار سوى استخدام واحد ينتهي_BIN
.إذا كانت البياناتNVARCHAR
ثم لا يهم الإعدادات المحلية التي يمكنك استخدامها كما هي كل نفس في هذه الحالة, ومن ثمLatin1_General_100_BIN2
يعمل دائما.إذا كانت البياناتVARCHAR
, يجب استخدام نفس الإعدادات المحلية أن البيانات حاليا (على سبيل المثالLatin1_General
,French
,Japanese_XJIS
, الخ) لأن لغة يحدد صفحة التعليمات البرمجية التي يتم استخدامها وتغيير صفحات التعليمات البرمجية يمكن أن يغير البيانات (أيفقدان البيانات). - باستخدام طول متغير نوع البيانات دون تحديد حجم سوف تعتمد على الحجم الافتراضي, و هناك نوعان مختلفان من التخلف اعتمادا على السياق حيث نوع البيانات المستخدمة.فهو إما 1 أو 30 أنواع السلاسل.عندما تستخدم مع
CONVERT()
فإنه سيتم استخدام 30 القيمة الافتراضية.الخطر هو ، إذا كانت السلسلة يمكن أن يكون أكثر من 30 بايت, وسوف تحصل على بصمت اقتطاع وأنت من المحتمل الحصول على نتائج غير صحيحة من هذا المسند. - حتى إذا كنت ترغب في قضية حساسة المقارنة ، ثنائي الترتيب هي لا حساسة لحالة الأحرف (آخر شائع).
لا ،
LIKE
ليس دائما حساسة لحالة الأحرف.ويستخدم ترتيب العمود المشار إليها ، أو ترتيب نسخ قاعدة البيانات إذا كان المتغير هو مقارنة سلسلة حرفية ، أو الترتيب المحدد عبر اختياريCOLLATE
البند.LCASE
لا SQL Server الوظيفة.يبدو أن إما Oracle أو MySQL.أو ربما Visual Basic ؟منذ سياق السؤال هو مقارنة عمود إلى سلسلة حرفية ولا ترتيب سبيل المثال (غالبا ما يشار إليها باسم "خادم") ولا ترتيب نسخ قاعدة البيانات لديك أي مباشر أثر هنا.الترتيب يتم تخزينها في كل عمود وكل عمود يمكن أن يكون لها ترتيب مختلف ، وتلك الترتيب لا تحتاج إلى نفس قاعدة البيانات الافتراضية الترتيب أو على سبيل المثال هذا الترتيب.بالتأكيد على سبيل المثال ترتيب النسخ الافتراضي هو ما قاعدة بيانات تم إنشاؤها حديثا سيتم استخدام افتراضي الترتيب إذا كان
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[_]%';
للحصول على مزيد من المعلومات على الترتيب, ترميزات ، وما إلى ذلك ، يرجى زيارة: الترتيب معلومات
ويمكنك إجبار قضية حساسة، والصب لثنائي متغير من هذا القبيل:
SELECT * FROM myTable
WHERE convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
وماذا قاعدة بيانات أنت؟ مع MS SQL Server، فإنه من إعداد قاعدة بيانات واسعة، أو يمكنك الإفراط في ركوب لكل الاستعلام مع الكلمة COLLATE.