2016-05-19 10 views
5

ओजेडीबीसी की नौकरियों में से एक ओरेकल डेटा प्रकारों को जावा प्रकारों में मैप करना है।ओजेडीबीसी 7 जावा डेटा स्ट्रिंग में CHAR डेटा प्रकार क्यों नहीं डालता है?

हालांकि, हमने देखा है कि यदि हम CHAR डेटा प्रकार देते हैं, तो यह java.lang.String पर मैप नहीं किया गया है। इस व्यवहार को दिखा रहे संस्करण हैं: ओजेडीबीसी 7 v12.1.0.2 और ओजेडीबीसी 6 v12.1.0.1। पुराने संस्करणों ने वास्तव में CHAR डेटा प्रकार को मानचित्र पर java.lang.String पर मानचित्रित किया था।

गहराई से खुदाई करने पर, हमने पाया कि StructMetaData ओजेडीबीसी के oracle.jdbc.driver पैकेज के भीतर है जो ओरेकल डेटा प्रकार जावा टाइप मैपिंग में लागू करता है। इसमें एक विधि है: 'getColumnClassName (int arg0)' जो ध्यान देने योग्य है। हमने देखा है कि OJDBC v7 के लिए, मामलों java.lang.String को मैप किया इस प्रकार हैं:

int arg1 = this.getColumnType(arg0); 
    switch (arg1) { 
    case -104: 
     return "oracle.sql.INTERVALDS"; 
    case -103: 
     return "oracle.sql.INTERVALYM"; 
    case -102: 
     return "oracle.sql.TIMESTAMPLTZ"; 
    case -101: 
     return "oracle.sql.TIMESTAMPTZ"; 
    case -15: 
    case -9: 
    case 12: 
     return "java.lang.String"; 
    ... 

हालांकि, बड़े OJDBC कार्यान्वयन के भीतर, इसे इस तरह देखा:

int arg1 = this.getColumnType(arg0); 
    switch (arg1) { 
    case -104: 
     return "oracle.sql.INTERVALDS"; 
    case -103: 
     return "oracle.sql.INTERVALYM"; 
    case -102: 
     return "oracle.sql.TIMESTAMPLTZ"; 
    case -101: 
     return "oracle.sql.TIMESTAMPTZ"; 
    case -15: 
    case -9: 
    case 1: 
    case 12: 
     return "java.lang.String"; 
    ... 

एक अतिरिक्त java.lang.String को मैप किया मामला नहीं है बाद के मामले में जैसे। 'मामला एक'। यह 'केस 1' ऊपर दिखाए गए पहले कोड स्निपेट में java.lang.String पर मैप नहीं किया गया है।

public String getColumnTypeName(int arg0) throws SQLException { 
    int arg1 = this.getColumnType(arg0); 
    int arg2 = this.getValidColumnIndex(arg0); 
    switch (arg1) { 
    case -104: 
     return "INTERVALDS"; 
    case -103: 
     return "INTERVALYM"; 
    case -102: 
     return "TIMESTAMP WITH LOCAL TIME ZONE"; 
    case -101: 
     return "TIMESTAMP WITH TIME ZONE"; 
    case -15: 
     return "NCHAR"; 
    case -13: 
     return "BFILE"; 
    case -9: 
     return "NVARCHAR"; 
    case -2: 
     return "RAW"; 
    case 1: 
     return "CHAR"; 
... 
इस वजह से

, हम OJDBC 7 या OJDBC6 v12.1.0.1 का उपयोग करता है, तो:

गहरी देख पर, यह 'मामले 1' एक ही StructMetaData वर्ग के getColumnTypeName(int arg0) विधि के भीतर CHAR को मैप किया है और CHAR एक स्तंभ के लिए डेटा प्रकार के रूप में निर्दिष्ट है, तो निम्न कोड इस स्तंभ के सूचकांक के लिए मंगलाचरण पर रिटर्न null:

for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) { 
    ... 
    resultSetMetaData.getColumnClassName(columnIndex) 
    ... 

अगर मैं (उदाहरण के लिए OJDBC जार के एक पुराने संस्करण की जगह: 11.2.0.3), फिर एक ही कोड देता है: java.lang.String। क्या यह एक बग है या इसे डिजाइन द्वारा हटा दिया गया है? क्या किसी को भी पहले एक ही समस्या का सामना करना पड़ा है?

+1

क्या आपने ड्राइवर के रिलीज नोट्स की जांच की है? अगर आपको लगता है कि यह गलत है, तो मेरा ओरेकल समर्थन के साथ एक एसआर खोलें। मैं पेशकश किए गए समाधान से सबसे ज्यादा खुश था। –

उत्तर

0

अच्छी पकड़ ...!

यह वास्तव में एक बग जैसा दिखता है; शायद इसके खिलाफ एकमात्र तर्क यह है कि यह ओरेकल द्वारा अविश्वसनीय रूप से बड़ी अनदेखी होगी।

प्रो बग:

  • पश्चगामी संगतता समस्या।JDBC ड्राइवर का अद्यतन कि स्पष्ट रूप से CHAR घोषणा
  • JPublisher Data Type and Java-to-Java Type Mappings के बारे में यह टिप्पणी पर निर्भर कर रहे हैं मौजूदा अनुप्रयोगों को बाधित होता 12C

के रूप में मानचित्रण (पहली पंक्ति ध्यान दें, CHAR प्रकार से संबंधित का वर्णन करता है जो java.lang.String के नक्शे)

| SQL and PL/SQL Data Type | Oracle Mapping | JDBC Mapping 
|------------------------- |------------------|----------------------------------------------- 
| CHAR, CHARACTER, LONG, |     | 
|STRING, VARCHAR, VARCHAR2 | oracle.sql.CHAR | java.lang.String 
| NCHAR, NVARCHAR2   | oracle.sql.NCHAR | oracle.sql.NString 
| NCLOB     | oracle.sql.NCLOB | oracle.sql.NCLOB 

बग के खिलाफ:

  • एक फैंसी परिकल्पना का तर्क हो सकता है कि ओरेकल समर्थित प्रकारों से CHAR एस को खारिज करने का प्रयास कर रहा है। दरअसल, CHAR प्रकार VARCHAR2 पर वास्तव में कोई लाभ नहीं है, और कुछ डाउनसाइड्स इसे कोई विकल्प नहीं बनाते हैं। अतीत में मुझे इस तथ्य से बहुत अच्छा लगा कि "CHAR" किसी अन्य आइटम को पूर्वनिर्धारित और अनिवार्य रूप से निश्चित लंबाई के साथ किसी आइटम को परिभाषित करने के आपके इरादे से संचार करता है, लेकिन यह इसे भी लागू नहीं करता है (यह केवल स्ट्रिंग को पैड करता है, अगर आप इसे भरते हैं बहुत कम मूल्य)। यदि आप रुचि रखते हैं, तो इस विषय के लिए समर्पित उत्कृष्ट पुस्तक Expert Oracle Database Architecture - Oracle Database 9i, 10g, and | Thomas Kyte | Apress में एक अनुभाग है। आप बिंदु पर Ask Tom "Char Vs Varchar" में एक अंश पढ़ सकते हैं, जहां लेखक स्वयं की पुस्तक उद्धरण:

तथ्य यह है कि एक CHAR/NCHAR वास्तव में एक VARCHAR2/NVARCHAR2 से ज्यादा कुछ नहीं में भेस मुझे राय के बनाता है कि वास्तव में केवल दो वर्ण स्ट्रिंग प्रकार हैं जिन्हें कभी भी विचार करना है, अर्थात् VARCHAR2 और NVARCHAR2। मुझे किसी भी एप्लिकेशन में CHAR प्रकार के लिए कभी भी उपयोग नहीं मिला है। चूंकि एक चार्ज प्रकार हमेशा परिणामी स्ट्रिंग को निश्चित चौड़ाई तक पैड करता है, इसलिए हम तेजी से खोजते हैं कि यह टेबल सेगमेंट और किसी भी इंडेक्स सेगमेंट में अधिकतम स्टोरेज का उपभोग करता है। यह काफी बुरा होगा, लेकिन CHAR/NCHAR प्रकारों से बचने के लिए एक और महत्वपूर्ण कारण है: वे उन अनुप्रयोगों में भ्रम पैदा करते हैं जिन्हें इस जानकारी को पुनर्प्राप्त करने की आवश्यकता होती है (कई इसे संग्रहीत करने के बाद अपने डेटा को "ढूंढ नहीं सकते")। इसका कारण चरित्र स्ट्रिंग तुलना के नियमों और उनके द्वारा किए गए कठोरता से संबंधित है। ....

[फिर एक ही उदाहरण में एक महान उदाहरण निम्नानुसार है; यह बहुत अच्छी तरह से लायक पढ़ने]

तथ्य यह है कि CHAR, अच्छा नहीं कर रहे हैं निश्चित रूप से कोई स्पष्ट सूचना के साथ मौजूदा अनुप्रयोगों को तोड़ने से Oracle औचित्य नहीं है की; तो परिकल्पना कि यह एक बग है स्पष्ट रूप से अधिक समझदार है।

यह देखते हुए कि सैद्धांतिक रूप से यह डाउनसाइड्स नहीं होगा, एक अत्यधिक कामकाज के रूप में आप अपने CHAR प्रकारों को VARCHAR2 के रूप में फिर से परिभाषित करने के लिए सभी शामिल तालिकाओं को बदल सकते हैं (यदि आप ऐसा करने के हकदार हैं, और यह व्यवहार्य है)।

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