একটি জাভা রেজাল্টসেট থেকে নাল ইন্ট মানের জন্য পরীক্ষা করা


277

জাভা আমি একটি নাল মান জন্য পরীক্ষার চেষ্টা করছি, একটি ResultSet, যেখানে কলামটি একটি আদিম কাস্ট করা হচ্ছে থেকে int- এ প্রকার।

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

উপরের কোড টুকরা থেকে, এটি করার আরও ভাল উপায় আছে এবং আমি ধরে নিই যে দ্বিতীয় দ্বিতীয় নাল () পরীক্ষাটি নিরর্থক ?

আমাদের শিক্ষিত করুন, এবং ধন্যবাদ


14
আমি এই প্রশ্নটি খুঁজে পেয়েছি কারণ আমার কাছে একটি ডাটাবেসে একটি অবনমিত কলাম রয়েছে এবং এটি জাভাতে কোনও পূর্ণসংখ্যার দ্বারা উপস্থাপিত। আপনি ভাববেন যে কোনও ডাটাবেসে একটি অণনীয় সংখ্যাসূচক কলাম থাকা যথেষ্ট পরিমাণে সাধারণ যে রেজাল্টসেট এপিআই এটিকে কিছুটা মার্জিতভাবে সামঞ্জস্য করবে।
spaaarky21

কারণ এটি স্পর্শিনী এবং এ পর্যন্ত সার্বজনীন থেকে আমি একজন উত্তর হিসাবে এই পোস্ট করার করছি না: এই আমার স্বাভাবিক সমাধান করা হয় IF(colName = NULL, 0, colName) AS colNameমধ্যে SELECT(ক সঞ্চিত proc মধ্যে বাঞ্ছনীয়) বিবৃতি। দার্শনিকভাবে এটি ডিবি অ্যাপ্লিকেশনটির সাথে সামঞ্জস্য করা উচিত কিনা, বা এর বিপরীতে আসে। যেহেতু এসকিউএল সহজেই নলগুলি পরিচালনা করে এবং অনেক এসকিউএল গ্রাহকরা (যেমন java.sql.ResultSet) না করেন, তাই সম্ভব হলে আমি ডিবিতে এটি পরিচালনা করি handle (এটি অবশ্যই অবশ্যই ধরে নেয় যে ধারণাগতভাবে NULL এবং শূন্য আপনার উদ্দেশ্যে সমান))
s.co.tt

উত্তর:


368

ডিফল্ট ResultSet.getIntযখন ক্ষেত্র মান NULLআসতে হয় 0, যা আপনার জন্য ডিফল্ট মান iValঘোষণা। এক্ষেত্রে আপনার পরীক্ষা সম্পূর্ণ অপ্রয়োজনীয়।

ক্ষেত্রের মানটি যদি নুল হয় তবে আপনি যদি অন্যরকম কিছু করতে চান তবে আমার পরামর্শ:

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

(নীচে @ মার্টিন মন্তব্য হিসাবে সম্পাদনা করা; লিখিত হিসাবে ওপি কোড সংকলন করা হবে না কারণ iValআরম্ভ করা হয়নি)


2
আমি ডক্সে ঠিক একই বিবৃতি পেয়েছি। এটি ইমোতে পৃথক থ্রেডের মূল্য। ( java.sun.com/j2se/1.4.2/docs/api/java/sql/… )
রোমান

6
@ রোমান - রেজাল্টসেটে getInt এর জন্য জাভাডোকটি দেখুন: "রিটার্ন: কলাম মান; যদি মান এসকিউএল নুল হয় তবে প্রাপ্ত মান 0"
কোয়ান

150
সত্যটি সত্যই হাস্যকর। getInt()হওয়া উচিত getInteger()যা ফেরৎ Integerযে nullযদি ডিবি মান null। ডেভস সত্যিই এই এক জড়ান।
ryantage

7
এই তর্কটি অনুসরণ করে @ স্যাকটিউ, এনপিই এড়ানোর জন্য জাভাতে সমস্ত কিছু তৈরি করা উচিত ছিল, যা এটি নয়। এনপিই এড়ানো অ্যাপ্লিকেশন বিকাশকারীদের দায়িত্ব, ভাষা অভ্যন্তরীণ এপিআইয়ের নয়।
ম্যাটিউস ভিকারি

10
ওএমজি কেন, কেবল 0NULL
শুল্ক

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কলিংটি অগত্যা কোনও পূর্ণসংখ্যা ফেরত দেয় না, কারণ ওরাকল ডিবিতে আমি কলামের ধরণের প্রকৃতির কারণে ("সংখ্যা")।
ম্যাট ম্যাক

ম্যাট একই সমস্যা ... মাইএসকিউএল এবং Types.BIGINT(এটি একটি এ ম্যাপ করা উচিত Long) সাথে getObject()পদ্ধতিটি শূন্যের পরিবর্তে 0 প্রদান করে।
xonya

2
এছাড়াও করতে rs.getObject("ID_PARENT", Integer.class)
পেরেছিলেন

26

ক্ষেত্রটি nullব্যবহার করছে কিনা তা পরীক্ষা করে দেখুন ResultSet#getObject()। সাবস্টিটিউট -1যদি আপনি চান যাই হোক না কেন নাল-কেস মান।

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

অথবা, যদি আপনি গ্যারান্টি দিতে পারেন যে আপনি সঠিক ডিবি কলামের প্রকারটি ব্যবহার করেছেন যাতে এটি ResultSet#getObject()সত্যিকার অর্থে একটি Integer(এবং এইভাবে না Long, Shortবা Byte) প্রদান করে, তবে আপনি এটি কেবল একটি এ টাইপকাস্ট করতে পারেন Integer

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

1
না, তবে এটি নন-নাল ক্ষেত্রে একটি অপ্রয়োজনীয় পূর্ণসংখ্যার অবজেক্ট তৈরি করবে। (এবং বিটিডব্লিউর বেশিরভাগ জেডিবিসি ড্রাইভাররা কোনও রেজাল্টসেট পদ্ধতি কল করার সময় একেবারেই ডিবিতে হিট করে না ... সাধারণত সমস্ত তথ্য তারের উপরে না আসা পর্যন্ত আপনি রেজাল্টসেটটি ফিরে পাবেন না)।
এরিকস

এটি আনার আকারের উপর নির্ভর করে। বেশিরভাগ ড্রাইভারের ক্ষেত্রে, ডিফল্টটি 10 ​​টি সারি হয় এবং একবার আনতে গেলে এগুলি প্রক্রিয়া করা হবে, তবে প্রক্রিয়াটি শেষ না হওয়া পর্যন্ত পরবর্তী সংগ্রহটি পুনরুদ্ধার করা হবে না।
ক্রিস্টো অুন

আমি অবাক হয়েছি যে আপনার উত্তরটি এর চেয়ে উত্তম উত্তর নয় :-) আমি ভোট দিয়েছি কারণ এটি সঠিক উত্তর যা খুব জটিল অনিরাপদ ছিল না () পদ্ধতিটি এড়ায়। আমার কাছে জাভা ;-) ব্যবহার বন্ধ করা এবং VB.Net ব্যবহার চালিয়ে যাওয়া এই পরিপূরক কারণ, যেখানে রেকর্ডসেট 10 বছরেরও বেশি সময় থেকে এই সহজ সমস্যার সমাধান করেছে!
স্ক্লেবে

11

আফাইক আপনি সহজেই ব্যবহার করতে পারেন

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

এমনকি যদি এটি NULL হয়।


5

জাভা জেনারিক্সের সাথে কেবল একটি আপডেট।

আপনি পূর্বে জাস্টিকৃত কোনও রেজাল্টসেট থেকে যেকোন জাভা জাতীয় anচ্ছিক মান পুনরুদ্ধার করতে একটি ইউটিলিটি পদ্ধতি তৈরি করতে পারেন।

দুর্ভাগ্যক্রমে, getObject (কলামনাম, ক্লাস) শূন্য করে না, তবে প্রদত্ত জাভা ধরণের জন্য ডিফল্ট মান, সুতরাং 2 টি কল প্রয়োজন

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));

সেক্ষেত্রে আপনি নিশ্চিত করে নিন যে এসকিউএল মানটি যদি নুল হয় তবে এনওয়াল নাল হবে (এবং শূন্য নয়)


2
কিন্তু resultSet.getInt("col_name")
19:40

1
এমএসএসকিউএল ডেটাসোর্স সহ, এটি কাজ করছে বলে মনে হয় না। এটির অতিরিক্ত চেক থাকা দরকারif (rs.wasNull())
alltej

1

সুবিধার্থে, আপনি রেজাল্টসেটের চারপাশে একটি মোড়কের ক্লাস তৈরি করতে পারেন যা নাল মান দেয় যখন 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

আপনার যদি এসকিউএল নিয়ন্ত্রণ থাকে তবে চেক করার আরেকটি দুর্দান্ত উপায় হ'ল আপনার ইনটি কলামের জন্য ক্যোয়ারীতেই একটি ডিফল্ট মান যুক্ত করা। তারপরে ঠিক সেই মানটি পরীক্ষা করে দেখুন।

যেমন একটি ওরাকল ডাটাবেসের জন্য এনভিএল ব্যবহার করুন

SELECT NVL(ID_PARENT, -999) FROM TABLE_NAME;

তারপরে চেক করুন

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

অবশ্যই এটি এই ধারণার অধীনে রয়েছে যে এমন একটি মান রয়েছে যা কলামে সাধারণত পাওয়া যায় না।


12
আমি এই উত্তরটি ভোট দিয়েছি কারণ এটি অনেক লোকের পক্ষে সমস্যা সৃষ্টি করার খুব সম্ভাবনা রয়েছে। যদি একটি অন্তর্ভুক্ত কলামটি নলযোগ্য হিসাবে সংজ্ঞায়িত হয় তবে ধনাত্মক সংখ্যা, শূন্য, নেতিবাচক সংখ্যা এবং NULL সমন্বিত মানগুলির একটি সেট রয়েছে। যেকোন সময় যেকোন সময় কেবল এই যাদু নম্বরযুক্ত ডেটার বৈধ সারি সন্নিবেশ করাতে পারে এবং হঠাৎ সমস্ত জিনিস খারাপ হয়ে যায়। এটি মূলত ম্যাজিক নম্বর অ্যান্টি প্যাটার্নের বাস্তবায়ন। এটি করবেন না।
ম্যাথিয়াস হ্রিণিজাক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.