2012-08-23 47 views
7

मल्टी-बाइट वर्णों के साथ मुझे बहुत दर्द हुआ है।सीएलओबी से VARCHAR2 तक जितना संभव हो उतना डेटा चुनें, डेटा

इस समस्या के लिए कोई सुझाव?

मैं एक CLOB क्षेत्र है कि पराक्रम कुछ मल्टी-बाइट वर्ण हैं, और मुझे एसक्यूएल में चुन सकते हैं और नीचे की प्रक्रिया के लिए एक स्ट्रिंग में इस क्षेत्र को बदलने की आवश्यकता है, वर्तमान में मैं उपयोग कर रहा हूँ:

SELECT DBMS_LOB.SUBSTR(description, 4000, 1) FROM table 

लेकिन उपरोक्त आदेश में 4000 बाइट्स के बजाए वर्णों की लंबाई में है। तो मुझे किसी भी बहु-बाइट वर्णों को संभालने के लिए 3000 में बदलना पड़ा जो डेटा में क्रिप्ट हो सकता है और बफर आकार त्रुटि होगी।

समस्या उन रिकॉर्ड्स के लिए है जिनमें मल्टीबाइट वर्ण नहीं है, यह अनावश्यक रूप से आवश्यकतानुसार अधिक डेटा को छोटा कर सकता है।

SELECT DBMS_LOB.SUBSTR(description, 4000bytes, 1) FROM table 

इस तरह मैं के रूप में ज्यादा डेटा बाहर निकल सकते हैं: (। 4000 स्ट्रिंग सीमा है, हम/उस के साथ रहना पड़ा सकता है)

वहाँ के बराबर में कुछ करने के लिए एक रास्ता है यथासंभव।

नोट: मैं बनाने की अनुमति नहीं कर रहा हूँ अस्थायी तालिकाओं/दृश्य, का उपयोग नहीं कर PL/SQL, केवल एसक्यूएल का चयन करें ...

उत्तर

4

शायद substr के साथ जिसके परिणामस्वरूप varchar2 काटना:

SELECT SUBSTRB(DBMS_LOB.SUBSTR(description, 4000, 1), 1, 4000) FROM table 
+0

कि हो नहीं करना चाहिए "... SUBSTRB के साथ"? (SUBSTR के बजाय SUBSTRB) –

+1

ब्याज से: क्या आप जानते हैं कि क्या होता है यदि पहले 3 9 99 वर्ण एक बाइट लंबे होते हैं और 4000 वां चरित्र एक बहु-बाइट होता है? क्या यह स्थिति 4000 पर गलत चरित्र नहीं लौटाएगा (क्योंकि यह मल्टी-बाइट चार के पहले बाइट को एकल-बाइट चार के रूप में व्याख्या करता है)? –

+2

कोई जेफ़री यह काम नहीं करेगा, अगर 'विवरण' में मल्टीबाइट वर्ण हैं, तो सबसे पहले डीबीएमएस_LOB.SUBSTR पहले से ही स्ट्रिंग बफर त्रुटि को SUBSTRB तक पहुंचने से पहले हिट करता है। – alchn

7

जेफरी की सोच प्रक्रिया ठीक है, लेकिन एलchn भी सही है। बस एक ही समस्या में भाग गया और मेरा समाधान यहाँ है। आप हालांकि एक समारोह बनाने में सक्षम हो करना होगा:

Create Or Replace Function clob_substr(p_clob In Clob 
             ,p_offset In Pls_Integer 
             ,p_length In Pls_Integer) Return Varchar2 Is 
Begin 
    Return substrb(dbms_lob.substr(p_clob 
           ,p_length 
           ,p_offset) 
       ,1 
       ,p_length); 
End; 
/

यहाँ है इसके बारे में एक डेमो फायदा नहीं है:

Select c 
     ,clob_substr(c 
        ,1 
        ,4000) 
    From (

     Select xmlelement("t", rpad('é', 4000, 'é'), rpad('é', 4000, 'é')).extract('//text()').getclobval() c 
      From dual 

     ); 
+1

मैंने https://bitbucket.org/janihur/orasql-ex/src/tip/clob-2.sql – user272735

+0

में इस उत्तर के आधार पर एक व्यापक (मुझे उम्मीद है!) उदाहरण बनाया है मैंने परीक्षण किया है और पुष्टि की है कि इस फ़ंक्शन का उपयोग करके जेफरी के समाधान से बेहतर काम करता है। हालांकि, मुझे समझ में नहीं आता क्यों। क्या यह वही सटीक बात नहीं कर रहा है, लेकिन इनलाइन की बजाय एक समारोह में? यह यहाँ एक फर्क क्यों पड़ता है? – KStensland

+0

मुझे संदेह है कि अंतर यह है कि पीएल/एसक्यूएल में वर्कर 2 32,767 बाइट तक जा सकता है, जबकि एसक्यूएल (कम से कम 11 जी और इससे पहले) अधिकतम अधिकतम 4,000 बाइट है। –