ওরাকলে কেস সংবেদনশীল অনুসন্ধান


228

এর ডিফল্ট আচরণ LIKEএবং অন্যান্য তুলনা অপারেটর, =ইত্যাদি কেস সংবেদনশীল।

এগুলি কি তাদের কেস-সংবেদনশীল করে তোলা সম্ভব?


বন্ধুত্বপূর্ণ অনুস্মারক যে ব্যবহারকারীর নামতে কোনও সূচক থাকা সত্ত্বেও উদাহরণের কয়েকটি অনুসন্ধানের ফলে পুরো টেবিল স্ক্যানের ফলাফল হবে।
জোনএসজি

8
আপনি কি REGEXP_LIKE(username,'me','i')লাইকের পরিবর্তে ব্যবহারের কথা বিবেচনা করেছেন ?
kubanczyk

5
না,
লাইকটি

উত্তর:


82

যেহেতু 10 জিআর 2, ওরাকল NLS_COMPএবং NLS_SORTসেশন প্যারামিটারগুলি সেট করে স্ট্রিং তুলনাগুলির আচরণকে সূক্ষ্ম সুরের অনুমতি দেয় :

SQL> SET HEADING OFF
SQL> SELECT *
  2  FROM NLS_SESSION_PARAMETERS
  3  WHERE PARAMETER IN ('NLS_COMP', 'NLS_SORT');

NLS_SORT
BINARY

NLS_COMP
BINARY


SQL>
SQL> SELECT CASE WHEN 'abc'='ABC' THEN 1 ELSE 0 END AS GOT_MATCH
  2  FROM DUAL;

         0

SQL>
SQL> ALTER SESSION SET NLS_COMP=LINGUISTIC;

Session altered.

SQL> ALTER SESSION SET NLS_SORT=BINARY_CI;

Session altered.

SQL>
SQL> SELECT *
  2  FROM NLS_SESSION_PARAMETERS
  3  WHERE PARAMETER IN ('NLS_COMP', 'NLS_SORT');

NLS_SORT
BINARY_CI

NLS_COMP
LINGUISTIC


SQL>
SQL> SELECT CASE WHEN 'abc'='ABC' THEN 1 ELSE 0 END AS GOT_MATCH
  2  FROM DUAL;

         1

আপনি কেস সংবেদনশীল সূচকগুলিও তৈরি করতে পারেন:

create index
   nlsci1_gen_person
on
   MY_PERSON
   (NLSSORT
      (PERSON_LAST_NAME, 'NLS_SORT=BINARY_CI')
   )
;

এই তথ্যটি ওরাকল কেসের সংবেদনশীল অনুসন্ধান থেকে নেওয়া হয়েছিল । নিবন্ধটিতে উল্লেখ করা হয়েছে REGEXP_LIKEতবে এটি ভাল পুরানোটির =সাথেও কাজ করবে বলে মনে হচ্ছে ।


10 জিআর 2 এর চেয়ে পুরানো সংস্করণগুলিতে এটি সত্যিই করা যায় না এবং যদি আপনার অ্যাকসেন্ট-সংবেদনশীল অনুসন্ধানের প্রয়োজন না হয় তবে সাধারণ পন্থাটি কেবল UPPER()কলাম এবং অনুসন্ধানের এক্সপ্রেশন উভয়েরই জন্য।


1
এটি ভালভাবে কাজ করে তবে এটি লাইক / = অপারেটরগুলি ব্যবহার করে খুব ধীরগতিতে হালনাগাদ করে তোলে ...... :(
সাকিব আলী

1
@ সাকিব আলি সালিশী LIKEঅভিব্যক্তি (উদাঃ WHERE foo LIKE '%abc%') ইতিমধ্যে যথেষ্ট ধীর হয়ে থাকে যদি সেগুলি সূচক করা যায় না, আমি মনে করি না এটি বিশেষত ক্ষেত্রে সংবেদনশীলতার সাথে সম্পর্কিত।
vলভারো গঞ্জালেজ

1
আপনি এগুলি এসকিউএলপিএলএসের বাইরেও শেল পরিবেশের মতো সেট করতে পারেন। উদাহরণস্বরূপ পার্ল স্ক্রিপ্ট ব্যবহার করে DBD::Oracleআপনি $ENV{NLS_SORT} = 'BINARY_CI'; $ENV{NLS_COMP} = 'LINGUISTIC';`ডিবিআই-> সংযোগ` কল করার আগে লিখতে পারেন`
mivk

আরে ALTER SESSIONআপনার সংশোধনটির স্থানীয় উদাহরণটি কেবলমাত্র পরিবর্তন করে এবং এর অর্থ কি এটি আপনার বর্তমান অধিবেশন যেমন ie যদি আমি বন্ধ করে আবার খুলি তবে এটি পুনরায় সেট হয়ে যাবে। এমন কোনও উপায় আছে যা আমি দেখতে পাচ্ছি যে বর্তমান মানগুলি কী তাই যাতে এটি সর্বত্র বজায় থাকলে আমি আবার মূল সেটিংসে ফিরে যেতে পারি ...
Seabizkit

305

পূর্ণ-পাঠ্য সূচকগুলি ব্যবহার না করে ওরাকলে কেস-সংবেদনশীল অনুসন্ধান করার 3 টি প্রধান উপায় রয়েছে।

শেষ পর্যন্ত আপনি কোন পদ্ধতিটি চয়ন করেন তা আপনার পৃথক পরিস্থিতিতে নির্ভর করে; মনে রাখার মূল বিষয় হ'ল পারফরম্যান্সের উন্নতি করতে আপনাকে কেস-সংবেদনশীল অনুসন্ধানের জন্য সঠিকভাবে সূচক করতে হবে।

1. আপনার কলাম এবং আপনার স্ট্রিংটি একইভাবে কেস করুন।

আপনি ব্যবহার করে UPPER()বা আপনার সমস্ত ডেটা একই কেস হিসাবে বাধ্য করতে পারেন LOWER():

select * from my_table where upper(column_1) = upper('my_string');

অথবা

select * from my_table where lower(column_1) = lower('my_string');

যদি column_1সূচিত না হয় upper(column_1)বা lower(column_1)যথাযথ হিসাবে, এটি একটি পূর্ণ টেবিল স্ক্যানকে বাধ্য করতে পারে। এটি এড়াতে আপনি একটি ফাংশন-ভিত্তিক সূচক তৈরি করতে পারেন ।

create index my_index on my_table ( lower(column_1) );

আপনি যদি পছন্দ মতো ব্যবহার করেন তবে আপনার %যে স্ট্রিংটি সন্ধান করছেন তার চারপাশে আপনাকে কিছুটা যুক্ত করতে হবে।

select * from my_table where lower(column_1) LIKE lower('my_string') || '%';

এই এসকিউএল ফিডল এই সমস্ত প্রশ্নের মধ্যে কী ঘটে তা প্রদর্শন করে। ব্যাখ্যা পরিকল্পনাগুলি নোট করুন, যা সূচক কখন ব্যবহার করা হচ্ছে এবং কখন তা নয় তা নির্দেশ করে।

২. নিয়মিত ভাব প্রকাশ করুন।

ওরাকল থেকে 10 গ্রাম এর পরে REGEXP_LIKE()উপলব্ধ। আপনি _ ম্যাচ_পরিমিতি_কে নির্দিষ্ট করতে পারেন'i' -সংবেদনশীল অনুসন্ধান সম্পাদনের জন্য আপনি ।

এটিকে সমতা অপারেটর হিসাবে ব্যবহার করতে আপনাকে অবশ্যই স্ট্রিংয়ের শুরু এবং শেষটি নির্দিষ্ট করতে হবে, যা ক্যারেট এবং ডলারের চিহ্ন দ্বারা চিহ্নিত করা হয়েছে।

select * from my_table where regexp_like(column_1, '^my_string$', 'i');

LIKE এর সমতুল্য সম্পাদন করতে, এগুলি সরানো যেতে পারে।

select * from my_table where regexp_like(column_1, 'my_string', 'i');

আপনার স্ট্রিংয়ে এমন অক্ষর থাকতে পারে যা নিয়মিত এক্সপ্রেশন ইঞ্জিন দ্বারা পৃথকভাবে ব্যাখ্যা করা হবে this

এই এসকিউএল ফিডল আপনাকে REGEXP_LIKE () ব্যবহার না করে একই উদাহরণ আউটপুট দেখায়।

৩. এটি সেশন পর্যায়ে পরিবর্তন করুন।

NLS_SORT প্যারামিটার ক্রম এবং বিভিন্ন তুলনা অপারেটর, সহ কোলেশন ক্রম নিয়ন্ত্রণ =কথা বলা ইত্যাদি। আপনি একটি বাইনারি নির্দিষ্ট করতে পারেন, কেস-সংবেদনশীল, সেশনটি পরিবর্তন করে বাছাই করুন। এর অর্থ হ'ল যে অধিবেশনটিতে করা প্রতিটি ক্যোয়ারি কেস-সংবেদনশীল পরামিতিগুলি সম্পাদন করবে।

alter session set nls_sort=BINARY_CI

ভাষাগত বাছাই এবং স্ট্রিং অনুসন্ধানের চারপাশে প্রচুর অতিরিক্ত তথ্য রয়েছে যদি আপনি কোনও আলাদা ভাষা নির্দিষ্ট করতে চান বা BINARY_AI ব্যবহার করে অ্যাকসেন্ট-সংবেদনশীল অনুসন্ধান করতে চান।

আপনাকে NLS_COMP পরামিতি পরিবর্তন করতে হবে ; উদ্ধৃতি থেকে:

সঠিক অপারেটর এবং কোয়েরি ক্লজগুলি যা এনএলএস_এসআরটি প্যারামিটার মান্য করে তা এনএলএস_সিএমপি প্যারামিটারের মানের উপর নির্ভর করে। যদি কোনও অপারেটর বা ধারাটি NLS_SORT মান না মানায়, NLS_COMP দ্বারা নির্ধারিত হিসাবে, ব্যবহৃত কোলেশনটি BINARY।

NLS_COMP এর ডিফল্ট মান BINARY; তবে, LingUistIC নির্দিষ্ট করে যে ওরাকলকে NLS_SORT এর মানের দিকে মনোযোগ দেওয়া উচিত:

WHLE ক্লজ এবং পিএল / এসকিউএল ব্লকে সমস্ত এসকিউএল অপারেশনের তুলনা NLS_SORT প্যারামিটারে বর্ণিত ভাষাগত বাছাই করা উচিত। কর্মক্ষমতা উন্নত করতে, আপনি কলামটিতে ভাষাগত সূচকটি সংজ্ঞায়িত করতে পারেন যার জন্য আপনি ভাষাগত তুলনা চান।

সুতরাং, আবারও আপনার সেশনটি পরিবর্তন করতে হবে

alter session set nls_comp=LINGUISTIC

ডকুমেন্টেশনে উল্লিখিত হিসাবে আপনি কর্মক্ষমতা উন্নত করতে একটি ভাষাগত সূচক তৈরি করতে চাইতে পারেন

create index my_linguistc_index on my_table 
   (NLSSORT(column_1, 'NLS_SORT = BINARY_CI'));

"একটি ফাংশন-ভিত্তিক সূচক তৈরি করুন" আশ্চর্যজনকভাবে এটি কী কী পার্থক্য করতে পারে
জ্যাকব গলডেন

আমি জিজ্ঞাসা করতে পারি যে এটির select * from my_table where lower(column_1) LIKE lower('my_string') || '%';পরিবর্তে করা কেন আলাদা select * from my_table where lower(column_1) LIKE lower('my_string%');? এটা কোন সুবিধা দেয়?
লোপেজভিট

1
এর একটি কারণ হ'ল যদি আপনার ক্যোয়ারিটি প্যারামারটেইজড হয় (সম্ভবত বেশিরভাগ পরিস্থিতিতে) তবে আপনার কলিং কোডটি সর্বদা @ লোপিজভিটকে সর্বদা%% যুক্ত করে তোলার দরকার নেই।
বেন

1
যদি এমন কিছু চরিত্র রয়েছে যা এর পরিণতিতে গোলমাল করবে regexp_like, তবে এরকম স্ট্রিংগুলি এড়ানোর কোনও উপায় আছে কি? একটি উদাহরণ দেওয়া, যদি স্ট্রিংটি $ থাকে তবে আউটপুটটি আমাদের প্রত্যাশা মতো হবে না। // সিসি @ বেন এবং অন্যরা দয়া করে শেয়ার করুন।
Bozzmob

2
` হ'ল পালানো চরিত্র @bozzmob। নিয়মিত এক্সপ্রেশনটি যে স্ট্রিংটিতে চলছে সেটিতে আউটপুটে কোনও পার্থক্য থাকতে হবে না $, এটি যদি $আপনার নিয়মিত অভিব্যক্তিতে আক্ষরিক প্রয়োজন হয় তবেই এটি আপনার সমস্যার কারণ হতে পারে । আপনি যদি একটি নির্দিষ্ট সমস্যা পেয়ে থাকেন তবে আমি অন্য প্রশ্ন জিজ্ঞাসা করব যদি এই মন্তব্য / উত্তরটি সহায়তা না করে থাকে।
বেন

51

সম্ভবত আপনি ব্যবহার চেষ্টা করতে পারেন

SELECT user_name
FROM user_master
WHERE upper(user_name) LIKE '%ME%'

3
ইনপুট প্যারামিটারটি পুরো আপার-কেস হয়ে থাকে এবং এটি কম বা মিশ্রিত না হলে এটি কাজ করে
সার্জিওনি

13
WHERE upper(user_name) LIKE UPPER('%ME%')তখন কি ভেবে দেখেছেন? :)
কনারাক

3
@ সার্জিওননি আপনার অবশ্যই অনুসন্ধানের শব্দটিকে বড় আকারের করতে হবে!
মার্কাস উইনান্দ

3
@ সার্জিওনি, আচ্ছা তবে আপনি কেন UPPERইনপুট প্যারামিটার ব্যবহার করবেন না ?
সিজনপ্রযুক্তি

5
@ ভি 4 ভেন্ডিটা upperফাংশনটি ব্যবহার করে আপনি সূচকটি হারাচ্ছেন, কীভাবে সূচকটি ব্যবহার করে অনুসন্ধান করবেন আপনার কোনও ধারণা আছে?
jcho360

7

ওরাকল 12 সি আর 2 থেকে আপনি ব্যবহার করতে পারেন COLLATE operator:

কলেট অপারেটর একটি অভিব্যক্তির জন্য কোলেশন নির্ধারণ করে। এই অপারেটরটি আপনাকে কোল্যাশনে ওভাররাইড করতে সক্ষম করে যে স্ট্যান্ডার্ড কোলেশন ডেরাইভেশন বিধি ব্যবহার করে ডেটাবেসটি অভিব্যক্তির জন্য উত্পন্ন করতে পারে।

COLLATE অপারেটর একটি আর্গুমেন্ট, কলেশন_নাম নেয়, যার জন্য আপনি একটি নামযুক্ত কোলেশন বা সিউডো-কোলেশন নির্দিষ্ট করতে পারেন। যদি কোলেশন নামে কোনও স্থান থাকে, তবে আপনাকে অবশ্যই নামটি ডাবল উদ্ধৃতি চিহ্নগুলিতে আবদ্ধ করতে হবে।

ডেমো:

CREATE TABLE tab1(i INT PRIMARY KEY, name VARCHAR2(100));

INSERT INTO tab1(i, name) VALUES (1, 'John');
INSERT INTO tab1(i, name) VALUES (2, 'Joe');
INSERT INTO tab1(i, name) VALUES (3, 'Billy'); 
--========================================================================--
SELECT /*csv*/ *
FROM tab1
WHERE name = 'jOHN' ;
-- no rows selected

SELECT /*csv*/ *
FROM tab1
WHERE name COLLATE BINARY_CI = 'jOHN' ;
/*
"I","NAME"
1,"John"
*/

SELECT /*csv*/ *
FROM tab1 
WHERE name LIKE 'j%';
-- no rows selected

SELECT /*csv*/ *
FROM tab1 
WHERE name COLLATE BINARY_CI LIKE 'j%';
/*
"I","NAME"
1,"John"
2,"Joe"
*/

ডিবি <> ফিডাল ডেমো


2
select user_name
from my_table
where nlssort(user_name, 'NLS_SORT = Latin_CI') = nlssort('%AbC%', 'NLS_SORT = Latin_CI')

%আপনার দ্বিতীয় প্রথম যুক্তি 's NLSSORTহয় না ওয়াইল্ডকার্ড, ডান হতে বোঝানো? তারা এক ধরণের বিভ্রান্তি।
স্টিফান ভ্যান ড্যান আকার

1

আপনি এর মতো কিছু করতে পারেন:

where regexp_like(name, 'string$', 'i');
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.