it-swarm.asia

كيفية إجراء بحث حساس لحالة الأحرف في عبارة WHERE؟

أريد بحث حساس لحالة الأحرف في استعلام SQL. ولكن بشكل افتراضي ، لا تنظر MySQL في حالة السلاسل.

أي فكرة عن كيفية إجراء بحث حساس لحالة الأحرف في استعلام SQL؟

22
Somnath Muluk

بشكل افتراضي ، لا تنظر MySQL في حالة السلاسل

هذا ليس صحيحا تماما. كلما create database في MySQL ، تحتوي قاعدة البيانات/المخطط على مجموعة أحرف وترتيب. كل مجموعة أحرف لها ترتيب افتراضي ؛ انظر هنا لمزيد من المعلومات.

الترتيب الافتراضي لمجموعة الأحرف latin1، الذي latin1_swedish_ci ، يصادف أنه غير حساس لحالة الأحرف.

يمكنك اختيار ترتيب حساس لحالة الأحرف ، على سبيل المثال latin1_general_cs ( قواعد MySQL ):

CREATE SCHEMA IF NOT EXISTS `myschema` 
DEFAULT CHARACTER SET latin1 
COLLATE latin1_general_cs ;

هذا له تأثير على أشياء مثل التجمع والمساواة. فمثلا،

create table casetable (
  id int primary key, 
  thing varchar(50)
);

select * from casetable;
+----+-------+
| id | thing |
+----+-------+
|  3 | abc   |
|  4 | ABC   |
|  5 | aBc   |
|  6 | abC   |
+----+-------+

في قاعدة بيانات حساسة لحالة الأحرف ، نحصل على:

select thing, count(*) from casetable group by thing;
+-------+----------+
| thing | count(*) |
+-------+----------+
| ABC   |        1 |
| aBc   |        1 |
| abC   |        1 |
| abc   |        1 |
+-------+----------+

select * from casetable where thing = "abc";
+----+-------+
| id | thing |
+----+-------+
|  3 | abc   |
+----+-------+

أثناء وجودنا في قاعدة بيانات غير حساسة لحالة الأحرف ، نحصل على:

select thing, count(*) from casetable group by thing;
+-------+----------+
| thing | count(*) |
+-------+----------+
| abc   |        4 |
+-------+----------+

select * from casetable where thing = "abc";
+----+-------+
| id | thing |
+----+-------+
|  3 | abc   |
|  4 | ABC   |
|  5 | aBc   |
|  6 | abC   |
+----+-------+

لاحظ أنه يمكنك أيضًا تغيير الترتيب من داخل استعلام . على سبيل المثال ، في حالة - قاعدة بيانات حساسة ، يمكنني القيام بذلك

select * from casetable where thing collate latin1_swedish_ci = "abc";
+----+-------+
| id | thing |
+----+-------+
|  3 | abc   |
|  4 | ABC   |
|  5 | aBc   |
|  6 | abC   |
+----+-------+
23
Matt Fenwick

يجب عليك دائمًا أن تذكر مع سؤالك إصدار MySQL الذي تستخدمه ، لأن MySQL في تطور مستمر.

حسنًا ، عد إلى سؤالك:

تعد دالات السلسلة في MySQL حساسة دائمًا لحالة الأحرف ، لذا يمكنك استخدام أي من الدالات LOCATE أو POSITION أو INSTR.

فمثلا:

SELECT phone FROM user WHERE POSITION('term' IN user_name)>0;

النمط المطابق مع التعبير العادي (RLIKE أو REGEXP) دائمًا حساس لحالة الأحرف لجميع إصدارات MySQL باستثناء الإصدار الأحدث 3.23.4.

فمثلا:

SELECT phone FROM user WHERE user_name REGEXP 'term';

بالنسبة لكل من المقارنة العادية (=) ومطابقة نمط SQL (LIKE) ، يعتمد السلوك على الحقول المعنية:

أ. CHAR ، VARCHAR ، وجميع متغيرات حقول TEXT تقارن حالة الأحرف غير الحساسة.

ب. CHAR BINARY ، VARCHAR BINARY وجميع أنواع حقول BLOB تقارن حساس لحالة الأحرف.

إذا قارنت حقلاً من (أ) بحقل من (ب) ، فستكون المقارنة حساسة لحالة الأحرف (يفوز حساسية الحالة). راجع الفصل "7.2.7 أنواع السلاسل" من دليل MySQL المرجعي وابحث عن العبارات المتعلقة بالفرز والمقارنات.

بدءًا من V3.23.0 ، من الممكن أيضًا إجراء مقارنة لحساسية الحالة مع عامل الإرسال BINARY ، بغض النظر عن أنواع الحقول المعنية. انظر الفصل "7.3.7 مشغلي Cast" من دليل MySQL المرجعي.

لذلك يمكنك أيضًا تغيير نوع اسم المستخدم ، أو باستخدام V3.23.x ، جرب شيئًا مثل:

SELECT phone FROM user WHERE BINARY username LIKE '%term%';
15
Turgut

في حالة وضعي ، أستخدم Access 2010 ، ولكن لدي نفس المشكلة ولكن الحل مختلف: استخدم StrComp() الدالة واختبار عودتها إلى الصفر.

StrComp( thing, 'abc', 0) = 0

لأن StrComp() تُرجع -1 إذا كانت الوسيطة الأولى "أصغر" ، 1 إذا كانت "أكبر" ، و 0 إذا كانت "متساوية" ، عندما StrComp()=0 ، لديك تطابق حساس لحالة الأحرف.

انظر هنا ، هنا أو هنا .

1
Martin F

سيعمل هذا في MySQL بغض النظر عن مجموعة الأحرف.

SELECT 'test' REGEXP BINARY 'TEST' AS RESULT;

وضع 'BINARY' يفرض مقارنة ثنائية.

1
user2288580