سؤال

عندما أكتب إجراءً مخزنًا لاختيار البيانات بناءً على متغير السلسلة (varchar، nvarchar، char) سأحصل على شيء مثل:

procedure dbo.p_get_user_by_username(
    @username      nvarchar(256)
as
begin
    select
        u.username
        ,u.email
        --,etc
    from
        sampleUserTable u
    where
        u.username = @username
end

وبعبارة أخرى، لمطابقة الرقم القياسي الذي سأحصل عليه

u.username = @username

لكن في بعض الأحيان أجد رمزًا يمكن استخدامه مثله بدلا من =

u.username like(@username)

متى ستستخدمه؟ألا ينبغي استخدام ذلك فقط عندما تحتاج إلى بعض مطابقة أحرف البدل؟

يحرر

شكرا على الإجابات.

أعتقد أنني بحاجة إلى توضيح أن ما كنت أحاول طرحه حقًا هو:إذا كان من الممكن أن يكون هناك موقف يُفضل فيه استخدام مثل بدلاً من "=" لمطابقة السلسلة تمامًا.من الإجابات أستطيع أن أقول أنه لن يكون هناك.من تجربتي الخاصة حتى في المواقف التي أحتاج فيها إلى تجاهل، على سبيل المثال حالة الأحرف والمسافات البادئة والنهائية، سأستخدم ltrim وrtrim وlow في كلتا السلسلتين ثم "=".شكرا مرة أخرى على المدخلات الخاصة بك.

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

المحلول

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

نصائح أخرى

صني تقريبا حصلت على حق :)

قم بتشغيل ما يلي في ضمان الجودة في التثبيت الافتراضي لـ SQL2005

select * from sysobjects where name = 'sysbinobjs   '
-- returns 1 row
select * from sysobjects where name like 'sysbinobjs   '
-- returns 0 rows

لذلك، لا يتطابق LIKE مع المسافات الزائدة، ففي جانب خطة الاستعلام، يعمل كلاهما بشكل متساوٍ تقريبًا، ولكن أداء الصلة '=' أفضل قليلاً.

هناك شيء إضافي يجب أن تضعه في الاعتبار عند استخدام LIKE وهو الهروب من السلسلة بشكل صحيح.

declare @s varchar(40) 
set @s = 'escaped[_]_%'

select 1 where 'escaped[_]_%'  like @s 
--Return nothing = BAD 

set @s = '_e_s_c_a_p_e_d_[___]___%' 

select 1 where 'escaped[_]_%'  like @s escape '_'
--Returns 1 = GOOD

بشكل عام، لا يستخدم الأشخاص LIKE للمطابقة التامة، لأن مشاكل الهروب تسبب كل أنواع التعقيدات والأخطاء الدقيقة، وينسى الناس الهروب وهناك عالم من الألم.

لكن ...إذا كنت تريد تطابقًا تامًا وفعالاً، فيمكن لـ LIKE حل المشكلة.

لنفترض أنك تريد مطابقة اسم المستخدم مع "sam" ولا تريد الحصول على "Sam" أو "Sam" وللأسف فإن ترتيب العمود غير حساس لحالة الأحرف.

شيء مثل ما يلي (مع إضافة الهروب) هو الطريق الصحيح.

select * from sysobjects
WHERE name = 'sysbinobjs' and name COLLATE Latin1_General_BIN LIKE 'sysbinobjs'

سبب إجراء المطابقة المزدوجة هو تجنب فحص الجدول.

لكن ....

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

إذا لم يتم استخدام أحرف البدل، فإن الفرق هو أن "=" يؤدي إلى تطابق تام، ولكن LIKE سيطابق سلسلة بمسافات زائدة (من SSBO):

عند إجراء مقارنات سلسلة مع مثل ، تكون جميع الأحرف في سلسلة الأنماط مهمة ، بما في ذلك المساحات الرائدة أو المتخلف.إذا كانت المقارنة في الاستعلام تهدف إلى إرجاع جميع الصفوف بسلسلة مثل "ABC" (ABC تليها مساحة واحدة) ، فإن صفًا لا يتم فيها إرجاع قيمة هذا العمود (ABC بدون مساحة).ومع ذلك ، يتم تجاهل الفراغات الزائدة ، في التعبير الذي يتطابق معه النمط.إذا كانت المقارنة في الاستعلام تهدف إلى إرجاع جميع الصفوف مع السلسلة مثل "ABC" (ABC بدون مساحة) ، يتم إرجاع جميع الصفوف التي تبدأ بـ ABC ولها صفر أو أكثر من الفراغات الزائدة.

مع ال يحب الكلمة الرئيسية التي يمكنك مطابقة الحقل u.username مقابل نمط محدد بدلاً من "سلسلة" ثابتة.

إذا كنت ترى هذا في تعليمات برمجية لأشخاص آخرين، فربما كانوا يقصدون السماح لشخص ما بتمرير سلسلة تتضمن نمطًا أو أحرف بدل.

نعم - أنت على حق - يجب استخدامه فقط لمطابقة أحرف البدل.يجب استخدامه بشكل مقتصد خاصة على الجداول الكبيرة جدًا في الحقول غير المفهرسة حيث يمكن أن يؤدي ذلك إلى إبطاء استعلاماتك بشكل كبير.

وقعت في نفس المشكلة.استغرق الأمر حوالي دقيقة ونصف لتشغيل استعلام مماثل =.عندما تغيرت = ل like كان الاستعلام أسرع بكثير.

  • حاول إنشاء فهرس للعمود الذي تقارن به.أدى هذا إلى تسريع الاستعلام بشكل ملحوظ.
  • حاول الجري sp_updatestats.في حالتي، أدى هذا إلى تشغيل الاستعلام في حوالي 6 ثوانٍ باستخدام = بدون الفهرس وعلى الفور تقريبًا مع الفهرس.

LIKE مخصص لمطابقة أحرف البدل، حيث أن = (يساوي) مخصص للمطابقات التامة.

أعتقد أيضًا أنه يستخدم للحقول التي تم فهرستها بواسطة كتالوجات النص الكامل لمقارنات السلسلة الأساسية.

نعم، على حد علمي، فإن استخدام like دون أي أحرف بدل هو نفس استخدام عامل التشغيل =.هل أنت متأكد من أن معلمة الإدخال لا تحتوي على أحرف بدل؟

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