এই কোয়েরিটি কেন কাজ করে?


37

আমার দুটি টেবিল রয়েছে, টেবিল_এ (আইডি, নাম) এবং টেবিল_বি (আইডি), আসুন ওরাকল 12 সি তে বলি।

এই কোয়েরি কেন একটি ব্যতিক্রম ফেরত দেয় না?

select * from table_a where name in (select name from table_b);

আমি যা বুঝি তার থেকে ওরাকল এটিকে দেখেন

select * from table_a where name = name;

তবে আমি যা পাই না তা কেন?

উত্তর:


61

ক্যোরিয়াম সিন্টেক্সিকভাবে এসকিউএল সঠিক হয়েছে এমনকি কলাম table_bনা থাকলেও name। কারণ স্কোপ রেজুলেশন।

কোয়েরিটি বিশ্লেষণ করা হলে, প্রথমে এটি পরীক্ষা করা হয় যে কলাম table_bআছে কিনা name। যেহেতু এটি হয় না, তারপরে table_aচেক করা হয়। টেবিলের কোনওটিতেই nameকলাম না থাকলে এটি ত্রুটি ফেলবে ।

অবশেষে ক্যোয়ারীটি এই হিসাবে কার্যকর করা হয়েছে:

select a.* 
from table_a  a
where a.name in (select a.name 
                 from table_b  b
                );

ফলাফলগুলি হিসাবে কোয়েরিটি প্রতিটি সারির জন্য দেবে table_a, সাবকিউরি (select name from table_b)- বা (select a.name from table_b b)- একই a.nameমান এবং একাধিক সারি সহ একক কলাম সহ একটি টেবিল table_b। সুতরাং, যদি table_b1 বা ততোধিক সারি থাকে তবে ক্যোয়ারীটি এইভাবে চলে:

select a.* 
from table_a  a
where a.name in (a.name, a.name, ..., a.name) ;

বা:

select a.* 
from table_a  a
where a.name = a.name ;

বা:

select a.* 
from table_a  a
where a.name is not null ;

যদি table_bখালি থাকে তবে কোয়েরিটি কোনও সারি ফেরত দেবে না (এই সম্ভাবনাটি দেখানোর জন্য @ উঘাইকে থ্যাঙ্কস)।


এটি (আপনি কোনও ত্রুটি না পেয়েছেন) সম্ভবত সর্বোত্তম কারণ হ'ল সমস্ত কলামের রেফারেন্সটি সারণির নাম / উপনামের সাথে উপসর্গ করা উচিত। যদি প্রশ্নটি ছিল:

select a.* from table_a where a.name in (select b.name from table_b); 

আপনি সরাসরি ত্রুটি পেয়েছে। যখন সারণি উপসর্গগুলি বাদ দেওয়া হয়, বিশেষত আরও জটিল প্রশ্নগুলিতে এবং এর চেয়েও গুরুত্বপূর্ণ, এ জাতীয় ভুল হওয়া খুব কঠিন নয় happen

এছাড়াও পড়ুন স্ট্যাটিক এসকিউএল স্টেটমেন্ট থাকা নামগুলি রেজোলিউশন: ওরাকল ডক্স অনুরূপ উদাহরণ বি-6 ইনার ক্যাপচার করুন এবং সুপারিশ মধ্যে নির্বাচন করুন এবং DML বিবৃতি এড়ানো ইনার ক্যাপচার অনুচ্ছেদ:

যথাযথ টেবিল উপন্যাস সহ বিবৃতিতে প্রতিটি কলাম রেফারেন্স যোগ্য করুন ify


কীভাবে আপনি এসকিউএল ইঞ্জিনের অভ্যন্তরীণ কাজগুলি এত নির্ভুলভাবে বিচ্ছিন্ন করেছিলেন?
রিঙ্কিপিংকু

8

কারণ

যখন কোনও নেস্টেড সাবকোয়ারি সাব-কোয়েরির উপরে এক স্তরের পিতামাতার বিবৃতিতে উল্লেখ করা একটি টেবিলের একটি কলামকে রেফার করে তখন ওরাকল একটি সম্পর্কিত সম্পর্কযুক্ত সাবকোয়ারি সম্পাদন করে। http://docs.oracle.com/cd/E11882_01/server.112/e41084/queries007.htm#SQLRF52357

এর অর্থ সাবক্রিওর সাথে সম্পর্কযুক্ত কিনা তা নির্ধারণের জন্য ওরাকলকে অবশ্যই বাইরের বিবৃতি প্রসঙ্গে সহ উপকণায় নামগুলি সমাধান করার চেষ্টা করতে হবে। এবং অপ্রত্যক্ষিতের জন্য nameএটিই কেবলমাত্র সমাধান সম্ভব।


4

কোনও nameক্ষেত্র নেই table_bতাই ওরাকল এটিকে এক থেকে নেয় table_a। আমি চেষ্টা করেছিলাম EXPLAIN PLANকিন্তু এটি আমাকে দিয়েছে কেবলমাত্র একটি TABLE ACCESS FULL। আমি অনুমান করি যে এটি উভয় টেবিলের মধ্যে কারটিশিয়ান পণ্য তৈরি করবে যা ফলস্বরূপ সমস্ত প্রশ্নের একটি তালিকা table_aউপ-কোয়েরির মাধ্যমে ফিরে আসে।


5
"টেবিল_বিতে কোনও নাম ক্ষেত্র নেই তাই ওরাকল একটিটিকে টেবিল_এ থেকে নেয়" " সঠিক। "আমি অনুমান করি যে এটি কোনও ধরণের কার্তেসিয়ান পণ্য উত্পন্ন করবে।" ভুল। ক্যোয়ারী আছে from table_a where ...। এটি নালাগুলি table_aব্যতীত সমস্ত সারি ফিরিয়ে দেবে name
ypercubeᵀᴹ

1
TABLE ACCESS FULLএটি কেবল ক্রিয়াকলাপের স্ক্যানটি করছে তা আপনাকে জানানোর উপায়।
জোশি বদিও

1
আপনার প্ল্যান অপ্রাসঙ্গিক - বিশাল টেবিলের সাথে ভালভাবে সূচক তৈরি হতে পারে - আমি ধরে নিচ্ছি যে পরীক্ষার ডেটাতে আপনার চালনা চলছে?
ভেরেস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.