2009-12-21 13 views
7

में SQL तर्क सीमा यह प्रतीत होता है कि ओरेकल एसक्यूएल में 1000 तर्कों की एक सीमा है। मैं जब इस तरह के रूप ....ओरेकल

select * from orders where user_id IN(large list of ids over 1000) 

मेरे वैकल्पिक हल के लिए एक अस्थायी तालिका बनाने के लिए, कि पहले में उपयोगकर्ता आईडी डालने के बजाय मानकों का एक विशाल सूची है कि JDBC के माध्यम से एक प्रश्न जारी करने है प्रश्नों पैदा करने के लिए इस में भाग आईएन में

क्या किसी को एक आसान कामकाज पता है? चूंकि हम हाइबरनेट का उपयोग कर रहे हैं, मुझे आश्चर्य है कि क्या यह स्वचालित रूप से पारदर्शी रूप से समान कार्य करने में सक्षम है।

+0

आपने पहली जगह में आईडी की बड़ी सूची कैसे बनाई? क्या वे एक टेबल या क्वेरी से आए थे? (मुझे किसी भी तरह से यूआई उत्पन्न हुआ है कि कई पैराम ...) – YogoZuno

+0

यह अक्सर होता है जब आईडी की सूची किसी अन्य स्रोत से आती है, जैसे एक खोज इंजन। यानी यह गैर-एकीकृत बैकएंड में सहसंबंध करने का एक तरीका है। – zzzeek

+0

आमतौर पर आईडी यूआई पर थोक संचालन करने वाले उपयोगकर्ता से आती है। – benstpierre

उत्तर

4

एक वैकल्पिक दृष्टिकोण डेटाबेस के लिए एक सरणी गुजरती हैं और में खंड में एक TABLE() समारोह का उपयोग करने के लिए होगा। यह शायद एक अस्थायी तालिका से बेहतर प्रदर्शन करेगा। यह कई प्रश्नों को चलाने से निश्चित रूप से अधिक कुशल होगा। लेकिन यदि आपके पास इस सामान को करने वाले सत्रों की बड़ी संख्या है तो आपको पीजीए मेमोरी उपयोग की निगरानी करने की आवश्यकता होगी। साथ ही, मुझे यकीन नहीं है कि इसे हाइबरनेट में तार करना कितना आसान होगा।

नोट: TABLE() फ़ंक्शन SQL इंजन में काम करते हैं, इसलिए उन्हें हमें SQL प्रकार घोषित करने की आवश्यकता होती है।

create or replace type tags_nt as table of varchar2(10); 
/

निम्नलिखित नमूना कुछ हज़ार यादृच्छिक टैग के साथ एक सरणी को पॉप्युलेट करता है। यह फिर एक क्वेरी के आईएन खंड में सरणी का उपयोग करता है।

declare 
    search_tags tags_nt; 
    n pls_integer; 
begin 

    select name 
    bulk collect into search_tags 
    from (select name 
      from temp_tags 
      order by dbms_random.value) 
    where rownum <= 2000; 

    select count(*) 
    into n 
    from big_table 
    where name in (select * from table (search_tags)); 

    dbms_output.put_line('tags match '||n||' rows!'); 
end; 
/
3

जब तक अस्थायी तालिका एक वैश्विक अस्थायी तालिका (यानी केवल सत्र के लिए दृश्यमान) है, यह चीजों को करने का अनुशंसित तरीका है (और मैं एक दर्जन से अधिक तर्कों के लिए उस मार्ग पर जाऊंगा, अकेले रहने दो एक हजार)।

मुझे आश्चर्य होगा कि आप कहां/कैसे 1000 तर्कों की सूची बना रहे हैं। यदि यह अर्ध-स्थायी समूह है (उदाहरण के लिए सभी कर्मचारी किसी विशेष स्थान पर आधारित होते हैं) तो वह समूह डेटाबेस में होना चाहिए और वहां शामिल होने चाहिए। डाटाबेस को वास्तव में जल्दी से जुड़ने के लिए डिज़ाइन और बनाया गया है। आईडी के पीछे एक गुच्छा को मध्य स्तर पर खींचने और फिर उन्हें डेटाबेस में वापस भेजने से बहुत तेज़।

select * from orders 
where user_id in 
(select user_id from users where location = :loc) 
1

"यदि ये आईडी आपके डेटाबेस में हैं, तो इसके बजाय जुड़ें/सहसंबंध का उपयोग करें" सत्य के बारे में टिप्पणी करें। हालांकि, यदि आपकी आईडी की सूची किसी अन्य जगह से आती है, तो एसओएलआर परिणाम की तरह, आप एकाधिक प्रश्न जारी करके अस्थायी तालिका आवश्यकता के आसपास हो सकते हैं, प्रत्येक में 1000 से अधिक आईडी मौजूद नहीं हैं, और फिर क्वेरी में क्वेरी के परिणामों को विलय कर सकते हैं। यदि आप हैशसेट की तरह एक अद्वितीय संग्रह में आईडी की प्रारंभिक सूची डालते हैं, तो आप एक समय में 1000 आईडी बंद कर सकते हैं।

3

आप 1000 के टुकड़ों में विभाजित करने के लिए सूची अतिरिक्त विधेय जोड़ सकते हैं:

select * from orders where user_id IN (<first batch of 1000>) 
OR user_id IN (<second batch of 1000>) 
OR user_id IN ...