2009-06-01 16 views
21

जैसे ही मेरी कोड मेरी while(rs.next()) पाश करने के लिए हो जाता है यह पैदा करता है ResultSet बंद अपवाद नहीं है। इस अपवाद का कारण क्या है और मैं इसके लिए कैसे सही कर सकता हूं?मैं जावा में ResultSet बंद अपवाद से कैसे बच सकता हूं?

संपादित करें: मैं अपने कोड है कि मैं एक और (rs2.next()) साथ while(rs.next()) पाश घोंसले हूँ में देखते हैं, दोनों परिणाम सेट एक ही डीबी से आ रही, यह कोई मुद्दा है?

+5

अपने कोड की एक सूची जोड़ें। – JeeBee

उत्तर

39

लगता है जैसे आपने पहले कथन से परिणाम सेट को पार करने से पहले एक ही कनेक्शन में एक और कथन निष्पादित किया था। यदि आप एक ही डेटाबेस से दो परिणाम सेट की प्रसंस्करण घोंसले कर रहे हैं, तो आप कुछ गलत कर रहे हैं। उन सेटों का संयोजन डेटाबेस पक्ष पर किया जाना चाहिए।

try { 
    Connection conn; 
    Statement stmt; 
    ResultSet rs; 

    try { 
     conn = DriverManager.getConnection(myUrl,"",""); 
     stmt = conn.createStatement(); 
     rs = stmt.executeQuery(myQuery); 

     while (rs.next()) { 
      // process results 
     } 

    } catch (SqlException e) { 
     System.err.println("Got an exception! "); 
     System.err.println(e.getMessage()); 
    } finally { 
     // you should release your resources here 
     if (rs != null) { 
      rs.close(); 
     } 

     if (stmt != null) { 
      stmt.close(); 
     } 

     if (conn != null) { 
      conn.close(); 
     } 
    } 
} catch (SqlException e) { 
    System.err.println("Got an exception! "); 
    System.err.println(e.getMessage()); 
} 

आप कनेक्शन (या बयान) बंद कर सकते हैं के बाद ही आप परिणाम सेट से परिणाम मिलता है:

+0

हाँ, मैंने जो किया, स्पष्टीकरण के लिए धन्यवाद। –

+4

यह सभी ड्राइवरों और आरडीबीएमएस के लिए सच नहीं है। –

+0

sqlserver.jar इसे घोंसला नहीं कर सकता है, लेकिन jtds.jar इसे कर सकता है। –

6

अपवाद कहा गया है कि अपने परिणाम बंद कर दिया है। आपको अपने कोड की जांच करनी चाहिए और उस स्थान की तलाश करनी चाहिए जहां आप ResultSet.close() कॉल जारी करते हैं। Statement.close() और Connection.close() के लिए भी देखें। निश्चित रूप से, उनमें से एक को rs.next() से पहले बुलाया जाता है।

4

आप बंद कर दिया हो सकता है या तो Connection या Statement कि ResultSet बनाया है, जो ResultSet तक ले जाएगा के रूप में अच्छी तरह से बंद कर दिया जा रहा है।

9

इसके अलावा, आप केवल एक ही परिणाम प्रत्येक कथन से खुला सेट कर सकते हैं। तो यदि आप एक ही समय में दो परिणाम सेट के माध्यम से पुनरावृत्त कर रहे हैं, तो सुनिश्चित करें कि उन्हें विभिन्न कथनों पर निष्पादित किया गया है। एक कथन पर दूसरा परिणाम सेट खोलने से पहले निकटता बंद हो जाएगी। http://java.sun.com/javase/6/docs/api/java/sql/Statement.html

4

उचित JDBC कॉल की तरह कुछ दिखना चाहिए। सबसे सुरक्षित तरीका finally ब्लॉक में करना है। हालांकि close()SqlException भी थ्रो कर सकता है, इसलिए अन्य try-catch ब्लॉक।

+1

प्यार करना चाहिए कि नेस्टेड कोशिश/पकड़ लें। कभी-कभी मैं वास्तव में जेडीबीसी से नफरत करता हूं। यह इस उदाहरण को फटकारता है लेकिन आपको वास्तव में परिणाम और कथन को बंद करना चाहिए। आपने इसे उचित जेडीबीसी कॉल कहा था! – banjollity

+0

एक चेक की आवश्यकता है यदि आरएस/एसटीएमटी/कॉन शून्य नहीं है ... –

+0

@DanielMagnusson आप सही हैं। मैंने जवाब तय कर लिया है। – Slartibartfast

17

यह ड्राइवर का उपयोग कर रहे सहित कई कारणों से, की वजह से हो सकता है।

क) कुछ ड्राइवरों नेस्टेड बयान अनुमति नहीं है। यदि आपका ड्राइवर जेडीबीसी 3.0 का समर्थन करता है तो आपको स्टेटमेंट ऑब्जेक्ट बनाते समय तीसरा पैरामीटर देखना चाहिए। उदाहरण के लिए, मुझे जेबर्ड ड्राइवर के साथ फायरबर्ड में भी यही समस्या थी, लेकिन कोड पोस्टग्रेस ड्राइवर के साथ ठीक काम करता था। फिर मैंने createStatement विधि कॉल में तीसरा पैरामीटर जोड़ा और इसे ResultSet.HOLD_CURSORS_OVER_COMMIT पर सेट किया, और कोड भी फायरबर्ड के लिए ठीक काम करना शुरू कर दिया।

static void testNestedRS() throws SQLException { 

    Connection con =null; 
    try { 
     // GET A CONNECTION 
     con = ConexionDesdeArchivo.obtenerConexion("examen-dest"); 
     String sql1 = "select * from reportes_clasificacion"; 

     Statement st1 = con.createStatement(
       ResultSet.TYPE_SCROLL_INSENSITIVE, 
       ResultSet.CONCUR_READ_ONLY, 
       ResultSet.HOLD_CURSORS_OVER_COMMIT); 
     ResultSet rs1 = null; 

     try { 
      // EXECUTE THE FIRST QRY 
      rs1 = st1.executeQuery(sql1); 

      while (rs1.next()) { 
       // THIS LINE WILL BE PRINTED JUST ONCE ON 
            // SOME DRIVERS UNLESS YOU CREATE THE STATEMENT 
       // WITH 3 PARAMETERS USING 
            // ResultSet.HOLD_CURSORS_OVER_COMMIT 
       System.out.println("ST1 Row #: " + rs1.getRow()); 

       String sql2 = "select * from reportes"; 
       Statement st2 = con.createStatement(
         ResultSet.TYPE_SCROLL_INSENSITIVE, 
         ResultSet.CONCUR_READ_ONLY); 

       // EXECUTE THE SECOND QRY. THIS CLOSES THE FIRST 
       // ResultSet ON SOME DRIVERS WITHOUT USING 
            // ResultSet.HOLD_CURSORS_OVER_COMMIT 

       st2.executeQuery(sql2); 

       st2.close(); 
      } 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } finally { 
      rs1.close(); 
      st1.close(); 
     } 

    } catch (SQLException e) { 

    } finally { 
     con.close(); 

    } 

} 

बी) आपके कोड में एक बग हो सकता है। याद रखें कि आप स्टेटमेंट ऑब्जेक्ट का पुन: उपयोग नहीं कर सकते हैं, एक बार जब आप एक ही कथन ऑब्जेक्ट पर कोई क्वेरी निष्पादित कर लेते हैं, तो कथन से जुड़े सभी खुले परिणाम बंद होते हैं। सुनिश्चित करें कि आप कथन बंद नहीं कर रहे हैं।

+0

मुझे फायरबर्ड जेडीबीसी ड्राइवरों के साथ एक ही समस्या थी। मैं सत्यापित कर सकता हूं कि 'ResultSet.HOLD_CURSORS_OVER_COMMIT' काम कर रहा है। –

+0

डीबी 2 ड्राइवरों पर भी इसी मुद्दे को इस ध्वज के साथ हल किया गया है! – bobbel

2

चेक कि क्या आप विधि जहां इस कोड static के रूप में क्रियान्वित किया जाता है घोषित किया है। यदि यह static है तो ResultSet को रीसेट करने वाला कुछ अन्य थ्रेड हो सकता है।

1

मुझे मिल ही गलती सब कुछ सही था केवल मैं ही बयान इंटरफ़ेस वस्तु उपयोग कर रहा था निष्पादित और डेटाबेस को अद्यतन करने के लिए। को अद्यतन करने और क्वेरी को क्रियान्वित करने के लिए अर्थात अलग बयान इंटरफेस के विभिन्न वस्तुओं इस्तेमाल करने के बाद मैं इस त्रुटि संकल्प लिया। अर्थात।इससे छुटकारा पाएं क्वेरी को अद्यतन और निष्पादित करने के लिए समान कथन ऑब्जेक्ट का उपयोग न करें।

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