Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

लूप के लिए ओरेकल SYS_REFCURSOR . में पुनरावृति नहीं करता है

निम्नलिखित विस्तारित टिप्पणियों पर ध्यान दें:

शायद सवाल के केंद्र में एक कर्सर क्या है की गलतफहमी है। यह रिकॉर्ड से भरा कंटेनर नहीं है, यह एक परिणाम सेट के लिए एक विनिर्देश है, जैसा कि एक समय में, एक एकल SQL क्वेरी के आधार पर। तो अगर आप

open rc for select id from table1;

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

एक प्रक्रिया के भीतर एक कर्सर में संग्रह का उपयोग करने के लिए, संग्रह प्रकार को एक अलग स्कीमा ऑब्जेक्ट के रूप में बनाया जाना चाहिए (हालांकि निश्चित रूप से आप अन्य प्रक्रियाओं में संग्रह प्रकारों का पुन:उपयोग कर सकते हैं, इसलिए यह उतना प्रतिबंधित नहीं है जितना लगता है)।

यदि आप एक प्रकार नहीं बना सकते हैं, तो देखें कि कौन से प्रकार पहले से मौजूद हैं जिनका आप उपयोग कर सकते हैं:

select owner, type_name
from   all_coll_types t
where  t.coll_type = 'TABLE'
and    t.elem_type_name = 'NUMBER';

उदाहरण के लिए:

create or replace type number_tt as table of number;

create table table1 (id primary key, currency, t_id) as
    select 10, 'GBP', 'PB1' from dual union all
    select 15, 'GBP', 'RB' from dual union all
    select 20, 'GBP', 'CC' from dual union all
    select 25, 'AUD', 'DC' from dual;

create table table2 (id,country,account) as
    select 10, 'UK', 'PB1' from dual union all
    select 15, 'Wales', 'RB' from dual union all
    select 20, 'SH', 'CC' from dual;

अब यह प्रक्रिया हो सकती है:

create or replace procedure myproc
    ( rc out sys_refcursor)
as
    l_names number_tt;
begin
    select id bulk collect into l_names
    from   table1
    where  currency = 'GBP';

    open rc for
        select t.id,t.country,t.account from table2 t
        where  t.id member of l_names;
end myproc;

कर्सर आउटपुट:

        ID COUNT ACC
---------- ----- ---
        10 UK    PB1
        15 Wales RB
        20 SH    CC

(मैंने i_id हटा दिया है आपकी प्रक्रिया में पैरामीटर क्योंकि मैं स्पष्ट नहीं था कि आप इसका उपयोग कैसे करना चाहते हैं।)

संभावित रूप से यह वास्तविक मुद्दे का एक सरलीकृत संस्करण है, क्योंकि जैसा कि यह खड़ा है आप पहली क्वेरी को सबक्वायरी के रूप में उपयोग कर सकते हैं और आपको संग्रह की आवश्यकता नहीं होगी:

create or replace procedure myproc
    ( rc out sys_refcursor)
as
begin
    open rc for
        select t.id,t.country,t.account from table2 t
        where  t.id in
               ( select id 
                 from   table1
                 where  currency = 'GBP' );
end myproc;

या बस इसमें शामिल हों, जैसा कि लिटिलफुट ने सुझाव दिया था:

create or replace procedure myproc
    ( rc out sys_refcursor)
as
begin
    open rc for
        select t2.id, t2.country, t2.account
        from   table1 t1
               join table2 t2 on t2.id = t1.id
        where  t1.currency = 'GBP';
end myproc;

हालाँकि, आपने उस उत्तर पर टिप्पणी की थी कि आप ऐसा नहीं कर सकते क्योंकि आपकी आवश्यकता इसे एक संग्रह, एक लूप, कुछ डक्ट टेप, दो बिल्लियों और एक फ्यूजन जनरेटर के माध्यम से करने की लग रही थी।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. VBA में किसी मौजूदा ऑब्जेक्ट द्वारा पहले से उपयोग किया जाने वाला नाम

  2. महीने के अंत में समान अवधियों को बाधित करें

  3. BEGIN - END PL/SQL में परमाणु लेनदेन को रोकता है

  4. ओरेकल डेटाबेस लिंक का उपयोग करने पर एक त्रुटि है ORA-12154 TNS निर्दिष्ट कनेक्ट पहचानकर्ता को हल नहीं कर सका

  5. Oracle नॉट इक्वल्स ऑपरेटर