2009-11-28 13 views
9

मुझे SQLite के लिए जेडीबीसी ड्राइवर में कोई समस्या है।जेडीबीसी चालक खाली परिणामसेट पर 0 परिणाम "परिणाम सेट बंद" अपवाद

मैं SELECT कथन के साथ एक क्वेरी निष्पादित कर रहा हूं।

यदि मुझे खाली ResultSet (0 पंक्तियां) मिलती हैं तो मुझे getString(1) पर कॉल करते समय "बंद परिणाम परिणाम" अपवाद दिखाई देता है।

बहुत पहले JDBC अनुभव के बिना

, मेरे सिद्धांत (जो मैं ResultSet के लिए Javadocs के माध्यम से इस बात की पुष्टि नहीं कर सकता है) कि

  • getString(1) एक खाली (शून्य पंक्ति) resultset पर काम नहीं करता है (डिजाइन द्वारा या की वजह से है एक बग)
  • ResultSet के "खुले" झंडा फिर से शून्य पंक्तियाँ (पर false के लिए सेट है, डिजाइन या एक बग)

से मैं इस bug report देखा था, लेकिन यकीन नहीं है अगर यह संबंधित है ।

मेरे qeustions हैं:

  1. सही ऊपर सिद्धांत है?
  2. क्या यह एक बग है? फ़ीचर? (और यदि हां, तो क्या कोई दस्तावेज़ीकरण को इंगित कर सकता है?)
  3. क्या यह सभी जेडीबीसी ड्राइवरों में एसक्यूएलटीई के जेडीबीसी या जेनेरिक ResultSet के लिए विशिष्ट है?
  4. इस तरह की चीजें करने का सही तरीका क्या है??

# 4 के लिए, मेरे समाधान की जाँच करने के लिए कि क्या किसी भी पंक्तियों परिणाम सेट में देखते हैं सही executeQuery() के बाद isFirst() कॉल उपयोग करने के लिए किया गया था। क्या यह सबसे अच्छा अभ्यास दृष्टिकोण है?

(मैं बस एक गिनती इंसेटैड का चयन भी कर सकता था क्योंकि मुझे वास्तव में परिणाम सेट की आवश्यकता नहीं थी, केवल शून्य-गैरजेरो ध्वज, लेकिन अगर मैं चयन के परिणामों की परवाह करता हूं तो मैं सही काम करना चाहता हूं)

धन्यवाद!

+1

सभी को धन्यवाद की तरह इस्तेमाल कर सकते हैं इस समस्या के इस तरह के लिए! बहुत रोशनी! – DVK

उत्तर

17

खाली है या नहीं, लेकिन ऐसा निम्नलिखित हमेशा दोषपूर्ण है:

resultSet = statement.executeQuery(sql); 
string = resultSet.getString(1); // Epic fail. The cursor isn't set yet. 

यह एक बग नहीं है। यह documented behaviour है। प्रत्येक decent JDBC tutorial इसका उल्लेख करता है। किसी भी डेटा तक पहुंचने में सक्षम होने से पहले आपको next() का उपयोग करके परिणामसेट के कर्सर को सेट करने की आवश्यकता है।

यदि आप वास्तव में रुचि रखते हैं कि अनुमानित अद्वितीय पंक्ति मौजूद है या नहीं, तो बस next() का परिणाम देखें। एक कल्पित UserDAO कक्षा में उदाहरण के लिए:

public boolean exist(String username, String password) throws SQLException { 
    boolean exist = false; 

    try (
     Connection connection = database.getConnection(); 
     PreparedStatement statement = connection.prepareStatement("SELECT id FROM user WHERE username = ? AND password = MD5(?)"); 
    ) { 
     statement.setString(1, username); 
     statement.setString(2, password); 

     try (ResultSet resultSet = statement.executeQuery()) { 
      exist = resultSet.next(); 
     } 
    } 

    return exist; 
} 

आप वास्तव में केवल शून्य या एक पंक्ति की उम्मीद है, तो बस की तरह कुछ कार्य करें:

public User find(String username, String password) throws SQLException { 
    User user = null; 

    try (
     Connection connection = database.getConnection(); 
     PreparedStatement statement = connection.prepareStatement("SELECT id, username, email, birthdate FROM user WHERE username = ? AND password = MD5(?)"); 
    ) { 
     statement.setString(1, username); 
     statement.setString(2, password); 

     try (resultSet = statement.executeQuery()) { 
      if (resultSet.next()) { 
       user = new User(
        resultSet.getLong("id"), 
        resultSet.getString("username"), 
        resultSet.getString("email"), 
        resultSet.getDate("birthdate")); 
      } 
     } 
    } 

    return user; 
} 

और फिर बस उस में तदनुसार संभाल व्यापार/डोमेन वस्तु, उदाहरण के लिए

public List<User> list() throws SQLException { 
    List<User> users = new ArrayList<User>(); 

    try (
     Connection connection = database.getConnection(); 
     PreparedStatement statement = connection.prepareStatement("SELECT id, username, email, birthdate FROM user"); 
     ResultSet resultSet = statement.executeQuery(); 
    ) { 
     while (resultSet.next()) { 
      users.add(new User(
       resultSet.getLong("id"), 
       resultSet.getString("username"), 
       resultSet.getString("email"), 
       resultSet.getDate("birthdate"))); 
     } 
    } 

    return users; 
} 

और फिर बस व्यापार/डोमेन वस्तु है, उदा तदनुसार इसे संभाल:

User user = userDAO.find(username, password); 

if (user != null) { 
    // Login? 
} 
else { 
    // Show error? 
} 

आप वास्तव में केवल शून्य या कई पंक्तियों की आशा करते हैं, तो बस कुछ पसंद है

List<User> users = userDAO.list(); 

if (!users.isEmpty()) { 
    int count = users.size(); 
    // ... 
} 
else { 
    // Help, no users? 
} 
+0

मैं कोड उदाहरणों की चौड़ाई के कारण इसे "स्वीकार" करने का चयन कर रहा हूं और डॉक्टर लिंक। – DVK

6
while (rs.next()) { 
// process the row 
} 
+0

यह उत्तर # 4 है। क्या # 1-3 abiout? :) – DVK

5
ResultSet के लिए

Javadocs से:

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

आपको पंक्ति पर ResultSet को स्थानांतरित करने की आवश्यकता होगी, उदा। किसी भी डेटा को पढ़ने का प्रयास करने से पहले, next() पर कॉल करके कॉल करके। यदि next() पर कॉल false देता है तो परिणाम सेट खाली होता है।

+0

यह उत्तर # 4 है। क्या # 1-3 abiout? :) – DVK

+0

@DVK 'ResultSet' को पंक्ति पर स्थित होने तक' getString' को कॉल करने का अर्थ नहीं है, इसलिए यह समझ में आता है कि यह एक अपवाद उठाता है (यह किसी भी जेडीबीसी ड्राइवर के लिए लागू होता है)। मुझे यकीन नहीं है कि आप 'परिणामसेट के "खुले" ध्वज "से क्या कह रहे हैं। –

+0

एक्लिप्स के डीबगर में, परिणाम सेट की जांच करते समय, "खुले" सदस्य का "झूठा" मान होता है। "परिणाम सेट बंद" अपवाद का कारण यही है (अंतर्निहित कारण नहीं, लेकिन तत्काल चर जो कि जेडीबीसी स्रोत में अपवाद उत्पन्न करने के लिए जांच की जाती है) – DVK

1

आपको लगता है कि

while(rs.next()) 
{ 
    String name=rs.getString("Name"); 
    int roll_no=Integer.parseInt(rs.getString("Roll")); 
} 
finally 
{ 
    try 
    { 
     rs.close(); 
     pst.close(); 
    } 
    catch(Exception ee) 
    { 
    } 
} 

Joptionpane.showmessahedialog(this,ee); 
+0

पोस्ट को प्रारूपित करने के लिए देखभाल करें। मैंने आपके उत्तर में से एक को स्वरूपित किया है, इसे जांचें और अन्य उत्तरों को प्रारूपित करें, यदि कोई हो! –

+0

thanx परेश मायानी मैं इस साइट के लिए नया हूँ। –

+0

कोई चिंता नहीं ... योगदान जारी रखें! –

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