जावा रिजल्टसेट से अशक्त इंट वैल्यू की जाँच करना


277

जावा में मैं एक परिणाम के लिए एक अशक्त मान के लिए परीक्षण करने की कोशिश कर रहा हूं, जहां कॉलम को एक आदिम अंतर प्रकार में डाला जा रहा है ।

int iVal;
ResultSet rs = magicallyAppearingStmt.executeQuery(query);
if (rs.next()) {
  if (rs.getObject("ID_PARENT") != null && !rs.wasNull()) {
    iVal = rs.getInt("ID_PARENT");
  }
}

ऊपर दिए गए कोड के टुकड़े से, क्या ऐसा करने का एक बेहतर तरीका है, और मुझे लगता है कि दूसरा Null () परीक्षण बेमानी है?

हमें शिक्षित करें, और धन्यवाद


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

मैं इसे एक उत्तर के रूप में पोस्ट नहीं कर रहा हूं क्योंकि यह स्पर्शरेखा और सार्वभौमिक से बहुत दूर है: मेरा सामान्य समाधान यह है कि इसे स्टेटमेंट IF(colName = NULL, 0, colName) AS colNameमें रखा जाए SELECT(अधिमानतः एक संग्रहीत खरीद में)। दार्शनिक रूप से यह नीचे आता है कि क्या DB को एप्लिकेशन के अनुरूप होना चाहिए, या इसके विपरीत। चूंकि SQL NULL को आसानी से हैंडल करता है और कई SQL उपभोक्ता (यानी java.sql.ResultSet) नहीं करते हैं , इसलिए जब संभव हो तो मैं इसे DB में हैंडल करने का विकल्प चुनता हूं। (यह, निश्चित रूप से मानता है कि वैचारिक रूप से NULL और शून्य आपके उद्देश्यों के लिए समान हैं।)
s.co.tt

जवाबों:


368

के लिए डिफ़ॉल्ट ResultSet.getIntजब फ़ील्ड मान है NULLवापस जाने के लिए है 0, जो भी आपके लिए डिफ़ॉल्ट मान है iValघोषणा। जिस स्थिति में आपका परीक्षण पूरी तरह से निरर्थक है।

यदि आप वास्तव में कुछ अलग करना चाहते हैं यदि फ़ील्ड मान NULL है, तो मैं सुझाव देता हूं:

int iVal = 0;
ResultSet rs = magicallyAppearingStmt.executeQuery(query);
if (rs.next()) {
    iVal = rs.getInt("ID_PARENT");
    if (rs.wasNull()) {
        // handle NULL field value
    }
}

(नीचे दिए गए @martin टिप्पणियों के रूप में संपादित; लिखित रूप में ओपी कोड संकलित नहीं किया जाएगा क्योंकि iVal)


2
मैंने अभी डॉक्स में वही स्टेटमेंट पाया है। यह एसओ इम्हो पर एक अलग धागे के लायक है। ( java.sun.com/j2se/1.4.2/docs/api/java/sql/… )
रोमन

6
@Roman - ResultSet में getInt के लिए javadoc देखें: "रिटर्न: स्तंभ मान; यदि मान SQL NULL है, तो लौटाया गया मान 0 है"
कोवान

150
सच, हास्यास्पद है। getInt()होना चाहिए getInteger()जो एक रिटर्न Integerहै कि nullअगर डीबी मूल्य है null। देवताओं ने वास्तव में इसे एक गड़बड़ कर दिया।
20

7
@sactiw इस तर्क के बाद, NPE से बचने के लिए जावा पर सब कुछ विकसित किया जाना चाहिए था, जो कि ऐसा नहीं है। एनपीई से बचें ऐप डेवलपर्स की जिम्मेदारी है, न कि भाषा आंतरिक एपीआई की।
मट्टुस विसकारी

10
OMG क्यों किया, बस NULL नहीं लौटा, 0और NULLदो बड़ी अलग चीजें हैं
deFreitas

84

एक और समाधान:

public class DaoTools {
    static public Integer getInteger(ResultSet rs, String strColName) throws SQLException {
        int nValue = rs.getInt(strColName);
        return rs.wasNull() ? null : nValue;
    }
}

27

मुझे लगता है, यह बेमानी है। यदि rs.getObject("ID_PARENT")किसी Integerवस्तु का nullमूल्य वास्तव में था, तो उसे वापस करना चाहिए NULL। तो ऐसा करना भी संभव होना चाहिए:

if (rs.next()) {
  Integer idParent = (Integer) rs.getObject("ID_PARENT");
  if (idParent != null) {
    iVal = idParent; // works for Java 1.5+
  } else {
    // handle this case
  }      
}

5
हम्म, कम से कम मेरे मामले में, इसके साथ समस्या यह है कि कॉलिंग getObjectअनिवार्य रूप से एक इंटर्जर नहीं लौटाता है, जो कि ओरेकल डीबी मैं उपयोग कर रहा है ("संख्या") में कॉलम प्रकार की प्रकृति के कारण है।
मैट मैक

मैट की एक ही समस्या ... MySQL के साथ और Types.BIGINT(कि एक को मैप किया जाना चाहिए Long) getObject()विधि शून्य के बजाय 0 देता है।
xonya

2
यह भी कर सकते हैंrs.getObject("ID_PARENT", Integer.class)
Arlo

26

बस जाँच करें कि क्या क्षेत्र nullउपयोग कर रहा है या नहीं ResultSet#getObject()-1जो भी अशक्त मामला मूल्य आप चाहते हैं के साथ स्थानापन्न ।

int foo = resultSet.getObject("foo") != null ? resultSet.getInt("foo") : -1;

या, यदि आप यह गारंटी दे सकते हैं कि आप सही DB कॉलम प्रकार का उपयोग करते हैं ताकि ResultSet#getObject()वास्तव में Integer(और इस तरह नहीं Long, Shortया Byte) वापस आए , तो आप इसे केवल टाइपकास्ट भी कर सकते हैं Integer

Integer foo = (Integer) resultSet.getObject("foo");

1
नहीं, लेकिन यह गैर-अशक्त मामले में एक अनावश्यक इंटेगर ऑब्जेक्ट का निर्माण करेगा। (और BTW सबसे JDBC ड्राइवर किसी भी परिणाम के दौरान db को हिट नहीं करते हैं, सभी पर कॉल करते हैं ... आम तौर पर आपको ResultSet वापस नहीं मिलता है जब तक कि सभी डेटा तार पर नहीं आ जाते हैं)।

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

मुझे आश्चर्य है कि आपका उत्तर बेहतर उत्तर नहीं है :-) मैं मतदान करता हूं क्योंकि यह उचित उत्तर है कि बहुत मुश्किल असुरक्षित से बचने के लिए अशक्त () विधि थी। मेरे लिए यह जावा ;-) का उपयोग बंद करने और VB.Net का उपयोग जारी रखने का एक पूरक कारण है, जहां रिकॉर्डसेट ने 10 से अधिक वर्षों से इस आसान समस्या को हल किया है!
schlebe

11

AFAIK आप बस का उपयोग कर सकते हैं

iVal = rs.getInt("ID_PARENT");
if (rs.wasNull()) {
  // do somthing interesting to handle this situation
}

भले ही वह NULL हो।


5

जावा पीढ़ी के साथ बस एक अद्यतन।

आप पहले दिए गए ResultSet से किसी भी जावा प्रकार के वैकल्पिक मान को प्राप्त करने के लिए एक उपयोगिता विधि बना सकते हैं।

दुर्भाग्य से, getObject (columnName, Class) शून्य नहीं लौटाता है, लेकिन दिए गए जावा प्रकार के लिए डिफ़ॉल्ट मान है, इसलिए कुछ कॉल की आवश्यकता होती है

public <T> T getOptionalValue(final ResultSet rs, final String columnName, final Class<T> clazz) throws SQLException {
    final T value = rs.getObject(columnName, clazz);
    return rs.wasNull() ? null : value;
}

इस उदाहरण में, आपका कोड नीचे की तरह दिखाई दे सकता है:

final Integer columnValue = getOptionalValue(rs, Integer.class);
if (columnValue == null) {
    //null handling
} else {
    //use int value of columnValue with autoboxing
}

प्रतिक्रिया पाकर खुशी हुई


2

आप इस पद्धति को परिणाम प्रकार और स्तंभ नाम में नंबर प्रकार का उपयोग करके कॉल कर सकते हैं। यह या तो इंटेगर मूल्य वापस कर देगा, या अशक्त। डेटाबेस में खाली मान के लिए कोई शून्य नहीं लौटाया जाएगा

private Integer getIntWithNullCheck(ResultSet rset, String columnName) {
    try {
        Integer value = rset.getInt(columnName);
        return rset.wasNull() ? null : value;
    } catch (Exception e) {
        return null;
    }
}

क्या आप कृपया इस बारे में अधिक विस्तार से जा सकते हैं कि यह प्रश्न कैसे हल करता है?
स्टर्लिंग आर्चर

आप इस विधि को परिणाम प्रकार और स्तंभ नाम में संख्या प्रकार का उपयोग करके कॉल कर सकते हैं। यह या तो इंटेगर मूल्य वापस कर देगा, या अशक्त। डेटाबेस में खाली मान के लिए कोई शून्य नहीं लौटाया जाएगा।
अमीन करिया

अति उत्कृष्ट! अपने उत्तर में संपादित करें (और संपादित करने के बाद टिप्पणी हटाएं) और आपके पास खुद एक अच्छा उत्तर है :)
स्टर्लिंग आर्चर

1

जावा 8 के साथ आप यह कर सकते हैं:

Long nVal = Optional.ofNullable(resultSet.getBigDecimal("col_name"))
                    .map(BigDecimal::longValue).orElse(null));

उस स्थिति में आप सुनिश्चित करते हैं कि SQL वैल्यू NULL है तो nVal शून्य (और शून्य नहीं) होगा


2
लेकिन लागू नहीं होता हैresultSet.getInt("col_name")
rapt

1
MSSQL डेटासोर्स के साथ, यह काम नहीं करता है। इसकी अतिरिक्त जांच की आवश्यकता हैif (rs.wasNull())
alltej

1

सुविधा के लिए, आप ResultSet के चारों ओर एक रैपर क्लास बना सकते हैं, जो अशक्त मूल्यों को लौटाता है जब ResultSetसामान्य रूप से नहीं होगा।

public final class ResultSetWrapper {

    private final ResultSet rs;

    public ResultSetWrapper(ResultSet rs) {
        this.rs = rs;
    }

    public ResultSet getResultSet() {
        return rs;
    }

    public Boolean getBoolean(String label) throws SQLException {
        final boolean b = rs.getBoolean(label);
        if (rs.wasNull()) {
            return null;
        }
        return b;
    }

    public Byte getByte(String label) throws SQLException {
        final byte b = rs.getByte(label);
        if (rs.wasNull()) {
            return null;
        }
        return b;
    }

    // ...

}

-6

चेक करने का एक और अच्छा तरीका है, यदि आपके पास एसक्यूएल का नियंत्रण है, तो अपने इंट कॉलम के लिए क्वेरी में एक डिफ़ॉल्ट मान जोड़ना है। तो बस उस मूल्य के लिए जाँच करें।

Oracle डेटाबेस के लिए, NVL का उपयोग करें

SELECT NVL(ID_PARENT, -999) FROM TABLE_NAME;

तो जाँच

if (rs.getInt('ID_PARENT') != -999)
{
}

बेशक यह भी इस धारणा के तहत है कि एक ऐसा मूल्य है जो सामान्य रूप से कॉलम में नहीं मिलेगा।


12
मैंने इस जवाब को वोट दिया क्योंकि इससे बहुत सारे लोगों के लिए समस्या पैदा होने की संभावना है। यदि अशक्त के रूप में परिभाषित एक अंतर स्तंभ में सकारात्मक संख्या, शून्य, नकारात्मक संख्या और NULL से मिलकर मूल्यों का एक सेट है। किसी भी समय कोई भी इस जादुई संख्या वाले डेटा की वैध पंक्ति सम्मिलित कर सकता है और अचानक सारी चीजें खराब हो जाएंगी। यह मूल रूप से जादू नंबर विरोधी पैटर्न का कार्यान्वयन है। यह मत करो।
मथायस ह्रीनिस्ज़क
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.