Java ResultSet öğesinden boş bir int değeri denetleme


277

Java sütun nerede ilkel bir int tür için bir ResultSet, null değeri test etmeye çalışıyorum .

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

Yukarıdaki kod parçası, bunu yapmak için daha iyi bir yolu var ve ben ikinci wasNull () test gereksiz olduğunu varsayalım ?

Bizi eğitin ve teşekkürler


14
Ben bir veritabanında nullable sütun var ve bu Java bir Tamsayı ile temsil çünkü bu soruyu buldum. Veritabanında boş bir sayısal sütuna sahip olmanın, ResultSet API'sinin onu biraz daha zarif bir şekilde barındıracak kadar yaygın olacağını düşünürsünüz.
spaaarky21

O teğet ve uzak evrensel gelen çünkü ben cevap olarak bu gönderme değilim: Bu Benim zamanki çözüm koymaktır IF(colName = NULL, 0, colName) AS colNameiçinde SELECT(tercihen bir saklı proc) deyimi. Felsefi olarak bu, DB'nin uygulamaya uyup uymayacağı ya da tam tersi olmalıdır. SQL NULL'ları kolayca işlediğinden ve birçok SQL tüketicisi (yani java.sql.ResultSet) yapmadığından , mümkün olduğunda DB'de işlemeyi tercih ederim. (Bu, elbette, kavramsal olarak NULL ve sıfırın amaçlarınız için eşdeğer olduğunu varsayar.)
s.co.tt

Yanıtlar:


368

İçin varsayılan ResultSet.getIntalan değeri olduğunda NULLdöndürmektir 0da varsayılan değer olan, iValbeyanı. Bu durumda testiniz tamamen yedeklidir.

Alan değeri NULL ise aslında farklı bir şey yapmak istiyorsanız, ben öneririm:

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

(Aşağıda @martin yorumları olarak düzenlendi; yazıldığı gibi OP kodu derlenmedi çünkü iValbaşlatılmadı)


2
Aynı ifadeyi dokümanlar içinde buldum. SO imho ayrı bir iş parçacığına değer. ( java.sun.com/j2se/1.4.2/docs/api/java/sql/… )
Roman

6
@Roman - ResultSet'te getInt için javadoc'a bakın: "Döndürür: sütun değeri; değer SQL NULL ise, döndürülen değer 0'dır"
Cowan

150
Gerçek şu ki saçma. getInt()olmalıdır getInteger()bir döndürür Integerolduğu nullDB değeri ise null. Geliştiriciler bunu gerçekten berbat etti.
ryvantage

7
@sactiw bu mantığı takip ederek, jpe'deki her şey NPE'yi önlemek için geliştirilmeliydi, ki durum böyle değil. NPE kaçının dil dahili API'leri değil, uygulama geliştiricilerin sorumluluğundadır.
Mateus Viccari

10
OMG Neden yaptı, sadece NULL 0NULL
döndürmüyor

84

Başka bir çözüm:

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

27

Bence gereksiz. rs.getObject("ID_PARENT")bir Integernesneyi döndürmeli veya nullsütun değeri gerçekte olsaydı NULL. Bu yüzden şöyle bir şey yapmak mümkün olmalı:

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
Hm, en azından benim durumumda, bu sorun getObject, kullandığım oracle db ("Sayı") sütun türünün doğası nedeniyle arama mutlaka bir tamsayı döndürmez olmasıdır.
Matt Mc

Matt ile aynı problem ... MySQL ile ve Types.BIGINT(a ile eşlenmesi gerekir Long) getObject()yöntem null yerine 0 değerini döndürür.
xonya

2
Ayrıca yapabilirdirs.getObject("ID_PARENT", Integer.class)
Arlo

26

Sadece alanın nullkullanılıp kullanılmadığını kontrol edin ResultSet#getObject(). Değiştirin -1istediğini boş durum değeri ile.

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

Veya, böylece doğru DB sütun türünü kullandığını garanti edemez eğer ResultSet#getObject()gerçekten döndürür Integer(ve böylece değil Long, Shortya Byte), sonra da yapabilirsiniz sadece kalıplaştığı bir etmek Integer.

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

1
Hayır, ancak boş olmayan durumda gereksiz bir Tamsayı nesnesi oluşturur. (Ve BTW çoğu JDBC sürücüsü herhangi bir ResultSet yöntemi çağrısı sırasında db'ye çarpmaz ... genellikle tüm veriler kablo üzerinden gelene kadar ResultSet'i geri alamazsınız).
EricS

Getirme boyutuna bağlıdır. Çoğu sürücüde, varsayılan değer 10 satırdır ve getirme alındıktan sonra işlenir, ancak işleme alınana kadar bir sonraki getirme alınmaz.
Kristo Aun

Ben senin cevabının daha iyi cevap olmadığını şaşırıyorum :-) Ben oy çünkü çok zor güvensiz güvenli wasNull () yöntemini önlemek uygun cevap. Benim için Java ;-) kullanmayı bırakmak ve RecordSet'in 10 yıldan fazla bir süredir bu kolay sorunu çözdüğü VB.Net'i kullanmaya devam etmek için ek bir neden!
schlebe

11

Sadece kullanabileceğiniz AFAIK

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

NULL olsa bile.


5

Java Generics ile bir güncelleme.

Daha önce yayınlanmış olan belirli bir ResultSet öğesinden herhangi bir Java türünün isteğe bağlı bir değerini almak için bir yardımcı program yöntemi oluşturabilirsiniz.

Ne yazık ki, getObject (columnName, Class) null döndürmez, ancak verilen Java türü için varsayılan değerdir, bu nedenle 2 çağrı gereklidir

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

Bu örnekte, kodunuz aşağıdaki gibi görünebilir:

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

Geri bildirim almaktan mutluyum


2

Bu yöntemi, resultsSet öğesini ve Number türüne sahip sütun adını kullanarak çağırabilirsiniz. Tamsayı değerini döndürür veya null değerini döndürür. Veritabanında boş değer için sıfır döndürülmeyecek

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

Bunun soruyu nasıl çözdüğü hakkında daha ayrıntılı bilgi verebilir misiniz?
Sterling Archer

Bu yöntemi, resultsSet öğesini ve Number türüne sahip sütun adını kullanarak çağırabilirsiniz. Tamsayı değerini döndürür veya null değerini döndürür. Veritabanında boş değer için sıfır döndürülmez.
amine kriaa

Mükemmel! Cevabınızı düzenleyin (ve düzenlemeden sonra yorumu silin) ​​ve kendinize iyi bir cevabınız var :)
Sterling Archer

1

Java 8 ile şunları yapabilirsiniz:

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

Bu durumda, SQL değeri NULL ise nVal değerinin boş (sıfır değil) olmasını sağlarsınız


2
ancak bu geçerli değildirresultSet.getInt("col_name")
rapt.

1
MSSQL veri kaynağı ile bu işe yaramıyor gibi görünüyor. Ek kontrole sahip olması gerekiyorif (rs.wasNull())
alltej

1

Kolaylık sağlamak için, ResultSet etrafında ResultSetnormalde olmazsa null değerleri döndüren bir sarmalayıcı sınıfı oluşturabilirsiniz .

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

SQL'iniz varsa, kontrol etmenin başka bir güzel yolu da int sütununuz için sorgunun kendisine varsayılan bir değer eklemektir. Sonra bu değeri kontrol edin.

örneğin bir Oracle veritabanı için NVL kullanın

SELECT NVL(ID_PARENT, -999) FROM TABLE_NAME;

sonra kontrol et

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

Tabii ki bu, normalde sütunda bulunmayan bir değerin olduğu varsayımı altındadır.


12
Bu cevaba oy verdim çünkü birçok insan için sorun yaratma olasılığı çok yüksek. Null değeri olarak tanımlanırsa int sütununda pozitif sayılar, sıfır, negatif sayılar ve NULL değerlerinden oluşan bir değer kümesi bulunur. Herhangi bir zamanda, bu sihirli numarayı içeren geçerli veri satırını ekleyebilir ve ani şeyler kötüleşir. Temelde sihirli sayı anti örüntüsünün uygulanmasıdır. Bunu yapma.
Matthias Hryniszak
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.