2009-11-25 7 views
27

ओरेकल में CLOB कॉलम के बाइट्स में आकार कैसे प्राप्त किया जाए?ओरेकल में एक सीएलओबी कॉलम के बाइट्स में आकार कैसे प्राप्त करें?

LENGTH() और DBMS_LOB.getLength()CLOB में उपयोग किए गए वर्णों की वापसी संख्या दोनों लेकिन मुझे यह जानने की ज़रूरत है कि कितने बाइट्स का उपयोग किया जाता है (मैं मल्टीबाइट वर्णमाला से निपट रहा हूं)।

+0

आप सीएलओबी के बाइट्स में आकार के साथ क्यों चिंतित हैं? – Thanatos

+1

ओपी नहीं, लेकिन मेरे मामले में मैं एक डीबी लिंक में सीएलओबीएस को पुनः प्राप्त कर रहा था और उन्हें 4000-बाइट भागों में काटना पड़ा, और मैं जानना चाहता था कि मुझे अपने डेटा के लिए कितने हिस्से की आवश्यकता है। –

+0

यह पागल है, मैं चीनी क्लोब को वर्चर 2 में निचोड़ना चाहता हूं और ऐसा नहीं कर सकता क्योंकि मैं आकार – Toolkit

उत्तर

13

के बाद कुछ सोच मैं इस समाधान के साथ आया था:

LENGTHB(TO_CHAR(SUBSTR(<CLOB-Column>,1,4000))) 

SUBSTR रिटर्न केवल पहले 4000 वर्ण (अधिकतम स्ट्रिंग आकार)

TO_CHARCLOB से VARCHAR2

LENGTHB रिटर्न में धर्मान्तरित स्ट्रिंग द्वारा प्रयुक्त बाइट्स में लंबाई।

+14

निर्धारित नहीं कर सकता लेकिन यह केवल तभी काम करता है जब आपका सीएलओबी छोटा हो। –

+1

आप कह सकते हैं 'LENGTHB (TO_CHAR (DBMS_LOB.SUBSTR (, 3000,1))) + एनवीएल (LENGTHB (TO_CHAR (DBMS_LOB.SUBSTR (, 3000,3001))), 0) '- यह 6000 तक काम करता है बाइट्स लेकिन अनिश्चित काल तक बढ़ाया जा सकता है। यदि आप बहु-बाइट वर्णमाला से निपट रहे हैं तो आपको 4000 से कम वर्णों को प्रतिस्थापित करने की आवश्यकता है, या आपको ORA-06501 वर्ण स्ट्रिंग बफर बहुत छोटा मिलेगा। यह भी ध्यान रखें कि DBMS_LOB.SUBSTR राशि और ऑफ़सेट पैरामीटर का क्रम बदलता है। –

+0

यह भी देखें http://stackoverflow.com/questions/10331912/performance-of-substr-on-clob – gavenkoa

-2

यह केवल 4000 बाइट तक काम करता है, क्या होगा अगर CLOB बड़ा 4000 से बाइट्स तो है हम उपयोग इस

declare 
v_clob_size clob; 

begin 

     v_clob_size:= (DBMS_LOB.getlength(v_clob))/1024/1024; 
     DBMS_OUTPUT.put_line('CLOB Size ' || v_clob_size); 
end; 

या

select (DBMS_LOB.getlength(your_column_name))/1024/1024 from your_table 
+0

लेकिन क्या DMBS_LOG.getlength (...) बाइट्स की बजाय वर्णों की संख्या वापस नहीं करता है? –

+0

उसने पहले से ही कहा है कि DBMS_LOB.getlength उसकी आवश्यकताओं के लिए अनुचित था ... – Reimius

10

मैं क्योंकि यह एक जवाब के रूप में मेरी टिप्पणी जोड़ रहा स्वीकार किए गए उत्तर की तुलना में मामलों की एक विस्तृत श्रृंखला के लिए मूल समस्या हल करता है। नोट: आपको अभी भी अधिकतम लंबाई और बहु-बाइट वर्णों के अनुमानित अनुपात को जानना चाहिए जो आपके डेटा में होंगे।

यदि आपके पास 4000 बाइट से अधिक CLOB है, तो आपको SUBSTR की बजाय DBMS_LOB.SUBSTR का उपयोग करने की आवश्यकता है। ध्यान दें कि राशि और ऑफ़सेट पैरामीटर DBMS_LOB.SUBSTR में उलट दिए गए हैं।

इसके बाद, आप, 4000 से कम एक राशि सबस्ट्रिंग है, क्योंकि इस पैरामीटर पात्रों की संख्या है आवश्यकता हो सकती है, और यदि आप मल्टी-बाइट वर्ण हो तो 4000 वर्ण से अधिक 4000 बाइट्स लंबा होगा और आपको ORA-06502: PL/SQL: numeric or value error: character string buffer too small मिलेगा क्योंकि सबस्ट्रिंग परिणाम को VARCHAR2 में फिट होना आवश्यक है जिसमें 4000 बाइट सीमा है। वास्तव में आप कितने पात्र पुनर्प्राप्त कर सकते हैं, आपके डेटा में प्रति वर्ण बाइट्स की औसत संख्या पर निर्भर करता है।

तो मेरी जवाब है:

LENGTHB(TO_CHAR(DBMS_LOB.SUBSTR(<CLOB-Column>,3000,1))) 
+NVL(LENGTHB(TO_CHAR(DBM‌​S_LOB.SUBSTR(<CLOB-Column>,3000,3001))),0) 
+NVL(LENGTHB(TO_CHAR(DBM‌​S_LOB.SUBSTR(<CLOB-Column>,6000,6001))),0) 
+... 

रूप में आप अपने सबसे लंबे समय तक CLOB को कवर, और औसत बाइट्स प्रति चरित्र अपने डेटा के के अनुसार हिस्सा आकार को समायोजित करने की जरूरत है, जहां आप के रूप में कई टुकड़ों में जोड़ें।

+0

एक लूप के रूप में व्यक्त की गई तकनीक के लिए TobiK द्वारा उत्तर देखें ताकि आपको यह जांचने की आवश्यकता न हो कि आपने अपने सबसे बड़े CLOB को कवर करने के लिए पर्याप्त भाग जोड़े हैं या नहीं । –

+0

तो यह समाधान ORA-06502 त्रुटियों से बचने के लिए आशा और अनुमान पर निर्भर करता है? निश्चित रूप से एक सीएलओबी को VARCHAR2 आकार के हिस्सों में विभाजित करने का एक मजबूत तरीका है! – PhilHibbs

+0

@ फिलहिब्स यह मेरे उद्देश्य के लिए पर्याप्त है क्योंकि मुझे केवल फ्रांसीसी से निपटना है और मल्टीबाइट वर्णों के अनुपात के बारे में धारणाएं कर सकते हैं। लेकिन मैं मानता हूं कि यह असंतोषजनक है और मुझे बेहतर जवाब देखने में खुशी होगी। –

4

यह एक CLOB के लिए VARCHAR2 से भी बड़ा आकार का प्रयास करें:

हम "VARCHAR2 संगत" आकार, CLOB डेटा के हर हिस्से के माध्यम से lengthb चलाने के कुछ हिस्सों में CLOB विभाजित है, और सभी परिणाम को संक्षेप में प्रस्तुत करने के लिए है।

declare 
    my_sum int; 
begin 
    for x in (select COLUMN, ceil(DBMS_LOB.getlength(COLUMN)/2000) steps from TABLE) 
    loop 
     my_sum := 0; 
     for y in 1 .. x.steps 
     loop 
      my_sum := my_sum + lengthb(dbms_lob.substr(x.COLUMN, 2000, (y-1)*2000+1)); 
      -- some additional output 
      dbms_output.put_line('step:' || y); 
      dbms_output.put_line('char length:' || DBMS_LOB.getlength(dbms_lob.substr(x.COLUMN, 2000 , (y-1)*2000+1))); 
      dbms_output.put_line('byte length:' || lengthb(dbms_lob.substr(x.COLUMN, 2000, (y-1)*2000+1))); 
      continue; 
     end loop; 
     dbms_output.put_line('char summary:' || DBMS_LOB.getlength(x.COLUMN)); 
     dbms_output.put_line('byte summary:' || my_sum); 
     continue; 
    end loop; 
end; 
/
+0

यह मेरे उत्तर से बेहतर है यदि आपको भविष्य में अधिकतम संभव सीएलओबी आकार के पूर्व * ज्ञान के बिना भविष्य में निष्पादन योग्य होने का अनुरोध चाहिए। हालांकि, मैं उस मामले में एक समारोह के रूप में लिखूंगा। –

3

एनवीएल (लंबाई (clob_col_name), 0) मेरे लिए काम करता है।

+0

नहीं, 'लंबाई' लंबाई * अक्षरों *, बाइट्स में लंबाई देता है। –

1

तालिका नाम का उपयोग कर dba_lobs से LOB सेगमेंट नाम देखें।

select TABLE_NAME,OWNER,COLUMN_NAME,SEGMENT_NAME from dba_lobs where TABLE_NAME='<<TABLE NAME>>'; 

अब dba_segments में उपयोग किए गए बाइट्स को खोजने के लिए सेगमेंट नाम का उपयोग करें।

select s.segment_name, s.partition_name, bytes/1048576 "Size (MB)" 
from dba_segments s, dba_lobs l 
where s.segment_name = l.segment_name 
and s.owner = '<<OWNER>> ' order by s.segment_name, s.partition_name; 
0

सरल समाधान सीएलओबी को बीएलओबी में डालना है और फिर बीएलओबी की लंबाई का अनुरोध करना है!

समस्या यह है कि ओरेकल एक समारोह है कि ब्लॉब को CLOB डाली नहीं है, लेकिन के बाइट्स

है हम केवल एक समारोह को परिभाषित कर सकते कि

create or replace 
FUNCTION clob2blob (p_in clob) RETURN blob IS 
    v_blob  blob; 
    v_desc_offset PLS_INTEGER := 1; 
    v_src_offset PLS_INTEGER := 1; 
    v_lang  PLS_INTEGER := 0; 
    v_warning  PLS_INTEGER := 0; 
BEGIN 
    dbms_lob.createtemporary(v_blob,TRUE); 
    dbms_lob.converttoblob 
     (v_blob 
     , p_in 
     , dbms_lob.getlength(p_in) 
     , v_desc_offset 
     , v_src_offset 
     , dbms_lob.default_csid 
     , v_lang, v_warning 
     ); 
    RETURN v_blob; 
END; 

एसक्यूएल आदेश संख्या प्राप्त करने का उपयोग करने के क्या करना है

SELECT length(clob2blob(fieldname)) as nr_bytes 

या

SELECT dbms_lob.getlength(clob2blob(fieldname)) as nr_bytes 

मैं Unico का उपयोग किए बिना Oracle 10g पर इस परीक्षण किया है डे (UTF-8)। लेकिन मुझे लगता है कि इस समाधान यूनिकोड (UTF-8) Oracle उदाहरण :-)

मुझे लगता है कि एक समाधान CLOB How convert CLOB to BLOB in Oracle? बूँद और इस पोस्ट में जर्मन लिखा करने के लिए कन्वर्ट करने के लिए पोस्ट किया गया है Nashev करने के लिए धन्यवाद प्रस्तुत करना चाहते हैं का उपयोग कर सही किया जाना चाहिए (कोड पीएल/एसक्यूएल में है) 13ter.info.blog जो ब्लॉब को क्लोब में परिवर्तित करने के लिए अतिरिक्त रूप से एक फ़ंक्शन देता है!

क्या कोई यूनिकोड (यूटीएफ -8) सीएलओबी में 2 कमांड का परीक्षण कर सकता है, तो मुझे यकीन है कि यह यूनिकोड के साथ काम करता है?

संबंधित मुद्दे