كيف تكتب استعلامًا غير حساس لحالة الأحرف لكل من MySQL وPostgres؟

StackOverflow https://stackoverflow.com/questions/203399

سؤال

أقوم بتشغيل قاعدة بيانات MySQL محليًا للتطوير، ولكنني أنشرها على Heroku الذي يستخدم Postgres.يتعامل Heroku مع كل شيء تقريبًا، لكن عبارات الإعجاب غير الحساسة لحالة الأحرف تصبح حساسة لحالة الأحرف.يمكنني استخدام عبارات iLike، لكن قاعدة بيانات MySQL المحلية الخاصة بي لا يمكنها التعامل مع ذلك.

ما هي أفضل طريقة لكتابة استعلام غير حساس لحالة الأحرف ومتوافق مع كل من MySQL وPostgres؟أو هل أحتاج إلى كتابة عبارات Like وiLike منفصلة اعتمادًا على قاعدة البيانات التي يتحدث إليها تطبيقي؟

هل كانت مفيدة؟

المحلول

select * from foo where upper(bar) = upper(?);

إذا قمت بتعيين المعلمة إلى الحالة العلوي في المتصل، ويمكنك تجنب استدعاء دالة الثانية.

نصائح أخرى

وإن المغزى من هذه القصة هي: لا تستخدم كومة برامج مختلفة لتطوير وإنتاج. أبدا.

وعليك فقط في نهاية المطاف مع البق التي لا يمكن استنساخها في ديف. والاختبار الخاص بك لا قيمة لها. فقط لا تفعل ذلك.

وعن طريق محرك قاعدة بيانات مختلفة غير وارد على الإطلاق - سيكون هناك المزيد FAR الحالات التي تتصرف بشكل مختلف عن مجرد مثل (أيضا، هل دققت في النسخ قيد الاستخدام من قبل قواعد البيانات هل هي متطابقة في كل حالة إذا لم يكن؟ ، يمكنك نسيان ORDER BY على أعمدة VARCHAR العمل نفسه)

استخدم AREL:

Author.where(Author.arel_table[:name].matches("%foo%"))

وmatches سوف تستخدم مشغل ILIKE لبوستجرس، وLIKE عن كل شيء آخر.

في بوستجرس، يمكنك القيام بذلك:

SELECT whatever FROM mytable WHERE something ILIKE 'match this';

ولست متأكدا إذا كان هناك ما يعادل ل MySQL ولكن يمكنك القيام به دائما هذا الذي هو قبيح قليلا ولكن يجب أن تعمل في كل من الخلية وبوستجرس:

SELECT whatever FROM mytable WHERE UPPER(something) = UPPER('match this');

هناك العديد من الإجابات، ولا شيء منها مرضٍ للغاية.

  • أقل (شريط) = أقل (؟) سوف عمل على MySQL وPostgres، ولكن من المحتمل أن يحدث ذلك أداء رهيب على MySQL:لن يستخدم MySQL فهارسه بسبب الدالة LOWER.في Postgres يمكنك إضافة فهرس وظيفي (on أقل (شريط)) لكن MySQL لا يدعم هذا.
  • سوف يقوم MySQL (ما لم تقم بتعيين ملف حساس لحالة الأحرف). التجميع) إجراء مطابقة غير حساسة لحالة الأحرف تلقائيًا، واستخدام فهارسها.(شريط = ؟).
  • من التعليمات البرمجية الخاصة بك خارج قاعدة البيانات، احتفظ بها حاجِز و bar_lower الحقول، حيث يحتوي bar_lower على نتيجة أقل (شريط).(قد يكون هذا ممكنًا باستخدام مشغلات قاعدة البيانات أيضًا).(انظر مناقشة هذا الحل على دروبال).هذا أمر أخرق ولكنه يعمل على الأقل بنفس الطريقة في كل قاعدة بيانات تقريبًا.

وREGEXP غير حساس لحالة الأحرف (إلا إذا استخدمت مع BINARY)، ويمكن استخدامها، مثل ذلك ...

    SELECT id FROM person WHERE name REGEXP 'john';

... لمطابقة 'جون'، 'JOHN'، 'جون'، وما إلى ذلك.

إذا كنت تستخدم كيو 8.4 يمكنك استخدام citext حدة لخلق حالة حقول النص حساسة.

وكنت قد تنظر أيضا التحقق من searchlogic المساعد، والتي لا في مثل / ILIKE التحول بالنسبة لك.

ويمكنك أيضا استخدام ~ * في بوستجرس إذا كنت تريد أن تطابق فرعية داخل كتلة. ~ مباريات لحالة الأحرف فرعية، ~ * قضية فرعية غير حساسة. في عملية بطيئة، ولكن ربما أجد أنه من المفيد لعمليات البحث.

Select * from table where column ~* 'UnEvEn TeXt';
Select * from table where column ~ 'Uneven text';

وكلا ستضرب على "بعض النص تفاوت هنا" فقط في السابق ستضرب على "بعض TEXT تفاوت هنا"

وتحويل إلى العلوي هو أفضل لأنه لا يغطي تركيب متوافق لالخلفيات قاعدة بيانات 3 الأكثر استخداما القضبان. الإنترنت، MySQL و سكليتي عن دعم هذا النحو. أنه يحتوي على (قاصر) العيب أن لديك إلى أحرف كبيرة سلسلة البحث في التطبيق الخاص بك أو في سلسلة شروط، مما يجعل من أقبح قليلا، ولكن أعتقد أن التوافق لك مكاسب يجعل من worthwile.

وكل من الخلية وSQLite3 ديك مشغل مثل تحسس حالة الأحرف. فقط كيو لديه مشغل لحالة الأحرف مثل ومحددة كيو (في دليل) مشغل ILIKE لعمليات البحث تحسس حالة الأحرف. قد تحدد ILIKE إنسياد للمثل في شروطكم على تطبيق القضبان، ولكن كن على علم بأن التطبيق سوف تتوقف عن العمل في ظل الخلية أو سكليتي.

وثمة خيار ثالث قد يكون للتحقق من محرك قاعدة البيانات التي تستخدمها وتعديل سلسلة البحث وفقا لذلك. قد يكون من الأفضل القيام بذلك عن طريق اختراق / monkeypatching محولات اتصال أكتيفيريكورد ولديك محول كيو تعديل سلسلة الاستعلام لتحل محل "LIKE" ل "ILIKE" قبل الاستعلام التنفيذ. هذا الحل ولكن معظم الملتوية، وعلى ضوء طرق أسهل مثل uppercasing التعبيرين، وأعتقد أن هذا لا worh الجهد (على الرغم من أنك سوف تحصل على الكثير من النقاط الكعكة لفعل ذلك بهذه الطريقة).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top