हाँ। एक LOB मेमोरी/डिस्क स्टोरेज के लिए एक पॉइंटर/संदर्भ है। आपको पहले स्टोरेज को "memalloc ()" (... इनिशियलाइज़) करना होगा, अपने LOB वेरिएबल के लिए पॉइंटर/रेफरेंस असाइन करना होगा। यही है dbms_lob.createTemporary()
के लिए है। जब तक आप एक वैध LOB लोकेटर के साथ LOB वैरिएबल को इनिशियलाइज़ नहीं करते हैं, उस LOB वैरिएबल पर आपके सभी ऑपरेशन ORA-22275: invalid LOB locator specified
के साथ विफल हो जाएंगे। ।
एन्हांसमेंट: क्या आपके पीएल/एसक्यूएल फ़ंक्शन को थोड़ा सा रिफैक्टर किया गया है:(और कृपया ध्यान दें कि मैंने last_60_cpu_cursor
के लिए एक डमी क्वेरी का उपयोग किया है। कर्सर. कर्सर का पुन:उपयोग न करें, अपना स्वयं का उपयोग करें! :-))
create or replace
function statistics_function
( namein in varchar2 )
return clob
is
line clob;
cursor last_60_cpu_cursor is
select 1 as last_60_cpu, sysdate as last_60_event_date
from dual
;
begin
dbms_lob.createtemporary(lob_loc => line, cache => true, dur => dbms_lob.call);
for cv in last_60_cpu_cursor loop
dbms_lob.append(line, to_char(cv.last_60_event_date)||'i'||to_char(cv.last_60_cpu)||chr(10));
end loop;
dbms_lob.append(line, 'last_60_cpu'||chr(10));
return line;
end statistics_function;
- आपको कर्सर को खोलने+लाने+बंद करने की आवश्यकता नहीं है। एक नियमित कर्सर-लूप ठीक काम करेगा (यदि और भी बेहतर नहीं, तो हुड के नीचे निहित बल्क-फ़ेचिंग के लिए धन्यवाद)।
- अस्थायी LOB को स्पष्ट रूप से कैश्ड घोषित करें (
cache => true
; जैसा कि आपके पास पहले से है)। यह सुनिश्चित करता है कि डिस्क (cache => false
पर जोड़े जाने के बजाय डेटा भाग को LOB में मेमोरी में जोड़ा जाता है। )। - LOB में जोड़ने के लिए स्ट्रिंग्स को संयोजित करें ताकि
dbms_lob.append()
पर कॉलों की संख्या कम से कम हो सके। । dbms_output.put_line()
हटाएं आपके फ़ंक्शन से। 32K से अधिक LOB सामग्री के मामले में, यह वैसे भी एक अपवाद होगा।
साथ ही, जब आप LOB को अपने Java env. पर वापस भेज दें, अस्थायी LOB मुक्त करें . (मैं जावा का लड़का नहीं हूं, मैं स्वयं जावा कोड स्निपेट नहीं लिख सकता।)
साथ ही, आपके जावा कोड में एक वैचारिक त्रुटि है; फ़ंक्शन की वापसी को Types.VARCHAR
. के रूप में पंजीकृत करना गलत है। इसके बजाय आपको Oracle के समर्पित CLOB प्रकार
का उपयोग करना चाहिए . (मैंने उन्हें C# में देखा है, Java में उन्हें भी होना चाहिए।)
साथ ही, आपके समाधान में एक प्रदर्शन समस्या है। आपका फ़ंक्शन एक LOB देता है। PL/SQL में, प्रत्येक फ़ंक्शन मान उसके कॉलर को आंतरिक मान की एक गहरी प्रति के रूप में वापस कर दिया जाता है। इसलिए, यदि आप किसी फ़ंक्शन से LOB लौटाते हैं, तो LOB सामग्री को एक नए LOB लोकेटर (/ सूचक/संदर्भ) के साथ पृष्ठभूमि में दोहराया जाता है। आपको उपयोग करना चाहिए आप किसी फ़ंक्शन के बजाय संग्रहीत कार्यविधि का उपयोग करने पर विचार कर सकते हैं और जावा को LOB को out nocopy
के रूप में पास कर सकते हैं पैरामीटर। तब संग्रहित खरीद इस तरह दिखेगी:
create or replace
procedure statistics_function
( namein in varchar2
, lob_out out nocopy clob )
is
cursor last_60_cpu_cursor is
select 1 as last_60_cpu, sysdate as last_60_event_date
from dual
;
begin
dbms_lob.createtemporary(lob_loc => lob_out, cache => true, dur => dbms_lob.session);
for cv in last_60_cpu_cursor loop
dbms_lob.append(lob_out, to_char(cv.last_60_event_date)||'i'||to_char(cv.last_60_cpu)||chr(10));
end loop;
dbms_lob.append(lob_out, 'last_60_cpu'||chr(10)||chr(10));
end statistics_function;
आपका जावा कॉल कैसा दिखेगा, यह आप पर निर्भर है और JDBC दस्तावेज़ ; लेकिन, निश्चित रूप से, इस तरह से लौटाए गए LOB का अर्थ होगा कि कोई पृष्ठभूमि सामग्री कॉपी नहीं हो रही है। बेशक, आवंटित अस्थायी LOB को मुक्त करने की आवश्यकता अभी भी लागू होती है।