सवाल जावा में ResultSet का उपयोग कर पंक्ति गणना कैसे प्राप्त करें?


मैं एक साधारण विधि बनाने की कोशिश कर रहा हूं जो एक परिणाम के रूप में एक परिणामसेट प्राप्त करता है और एक int देता है जिसमें परिणामसेट की पंक्ति गणना शामिल होती है। क्या यह ऐसा करने का एक वैध तरीका है या इतना नहीं?

int size = 0;
    try {
        while(rs.next()){
            size++;
        }
    }
    catch(Exception ex) {
        System.out.println("------------------Tablerize.getRowCount-----------------");
        System.out.println("Cannot get resultSet row count: " + ex);
        System.out.println("--------------------------------------------------------");
    }

मैंने कोशिश की:

int size = 0;
try {
    resultSet.last();
    size = resultSet.getRow();
    resultSet.beforeFirst();
}
catch(Exception ex) {
    return 0;
}
return size;

लेकिन मुझे एक त्रुटि कह रही है com.microsoft.sqlserver.jdbc.SQLServerException: The requested operation is not supported on forward only result sets.

पॉइंटर्स के लिए अग्रिम धन्यवाद!


56
2017-10-25 08:16


मूल


क्या आप एसक्यूएल कथन को बदल नहीं सकते हैं SELECT COUNT(*) ...? - Moyshe
परिणामसेट भरने वाली क्वेरी का आविष्कार करने से पहले आप "चयन गिनती (*)" क्यों नहीं करते हैं? हालांकि फॉरवर्ड केवल आरएस इस बात पर निर्भर करता है कि आप कनेक्शन कैसे खोलते हैं (पास करने के लिए कुछ पैरा हैं)। विवरण के लिए अपने जेडीबीसी चालक दस्तावेज देखें। - BigMike
(ओटी; आप एक वास्तविक लॉगिंग लाइब्रेरी का उपयोग करने पर विचार करना चाहेंगे जो विधि नाम आदि जैसे चीजों का ख्याल रखेगा) - Dave Newton


जवाब:


यदि आपके पास तैयार किए गए कथन तक पहुंच है जिसके परिणामस्वरूप परिणामस्वरूप आप इसका उपयोग कर सकते हैं

connection.prepareStatement(sql, 
  ResultSet.TYPE_SCROLL_INSENSITIVE, 
  ResultSet.CONCUR_READ_ONLY);

यह आपके कथन को इस तरह से तैयार करता है कि आप कर्सर को रिवाइंड कर सकते हैं। यह भी दस्तावेज में है परिणाम जैवडोक

आम तौर पर, हालांकि, बड़े परिणाम सेट के लिए कर्सर को अग्रेषित करना और रीवाइंड करना काफी अक्षम हो सकता है। SQL सर्वर में एक अन्य विकल्प सीधे आपके SQL कथन में पंक्तियों की कुल संख्या की गणना करना होगा:

SELECT my_table.*, count(*) over (partition by 1) total_rows
FROM my_table
WHERE ...

52
2017-10-25 08:20



मेरे पास तैयार कथन तक पहुंच है, लेकिन वास्तव में एसक्यूएल में वास्तव में सक्षम नहीं है। वर्तमान तैयार कथन इस तरह दिखता है: "m.messageGUID = i.MessageGuid पर i.requestfield = 'DR' और i.indexValue '% TAGER00%' 'जैसे' m.messageGUID = 'DR' और i.indexValue पर [संदेश] एम INNER जॉइन RequestMessageIndex से एम का चयन करें।" क्या मुझे बस SQL ​​कथन में कुछ कोड जोड़ना है या कोई अन्य कथन बनाना है? क्षमा करें, जब मैं एसक्यूएल की बात करता हूं तो मैं वास्तव में गूंगा हूं ... - Tiwaz89
@DeanGrobler: इन चीजों को पूछने में कुछ भी गलत नहीं है! मैंने जो विकल्प सुझाए हैं वे वैध हो सकते हैं। किसी भी मामले में, पंक्तियों की संख्या गिनती किसी भी तकनीक के साथ प्रदर्शन को प्रभावित कर सकती है। मैं व्यक्तिगत रूप से एक गणना का उपयोग कर दूसरा, पसंद करते हैं count(*) over (partition by 1) फ़ील्ड, लेकिन केवल अगर आप जीयूआई में पेजिंग जैसी चीजों के लिए उस गिनती का उपयोग कर सकते हैं। अगर यह केवल लॉगिंग के बारे में है, तो मुझे यकीन नहीं है कि आम तौर पर पंक्ति गणना प्राप्त करना एक अच्छा विचार है ... - Lukas Eder
परिणामस्वरूप की पंक्ति गणना प्राप्त करने के लिए यह आवश्यक है, चर का उपयोग जीयूआई के लिए लौटाए गए डेटा के आसपास एक गतिशील तालिका बनाने के लिए किया जाना चाहिए, इसलिए इसे करने के लिए डिफ को जाना होगा। प्लस तरफ, लौटाया जा रहा डेटा एक खोज समारोह से है। तो परिणाम पंक्तियां केवल 15 पंक्तियों अधिकतम होगी। - Tiwaz89
@DeanGrobler: यदि आप जानते हैं कि आप अधिकतम 15 पंक्तियों के बारे में बात कर रहे हैं, तो आप दोनों विकल्पों के साथ सुरक्षित पक्ष पर हैं। - Lukas Eder


आपके एसक्यूएल स्टेटमेंट बनाने कोड की तरह हो सकता है

statement = connection.createStatement();

"Com.microsoft.sqlserver.jdbc.SQLServerException को हल करने के लिए: अनुरोधित ऑपरेशन केवल आगे के परिणाम सेट पर समर्थित नहीं है" कोड के ऊपर अपवाद परिवर्तन

statement = connection.createStatement(
    ResultSet.TYPE_SCROLL_INSENSITIVE, 
    ResultSet.CONCUR_READ_ONLY);

उपरोक्त परिवर्तन के बाद आप इसका उपयोग कर सकते हैं

int size = 0;
try {
    resultSet.last();
    size = resultSet.getRow();
    resultSet.beforeFirst();
}
catch(Exception ex) {
    return 0;
}
return size;

पंक्ति गणना प्राप्त करने के लिए


24
2018-06-26 05:34





Statement s = cd.createStatement();
ResultSet r = s.executeQuery("SELECT COUNT(*) AS rowcount FROM FieldMaster");
r.next();
int count = r.getInt("rowcount");
r.close();
System.out.println("MyTable has " + count + " row(s).");

कभी-कभी जेडीबीसी निम्नलिखित विधि का समर्थन नहीं करता है, इस समाधान का उपयोग 'TYPE_FORWARD_ONLY' जैसी त्रुटि देता है

एसक्लाइट जेडीबीसी में समर्थन नहीं करता है।

resultSet.last();
size = resultSet.getRow();
resultSet.beforeFirst();

तो उस समय इस समाधान का उपयोग करें।

धन्यवाद..


21
2018-01-29 05:16





एक करो SELECT COUNT(*) FROM ... इसके बजाय क्वेरी।


6
2018-01-29 05:37





मैंने अभी गेटटर विधि बनाई है।

public int getNumberRows(){
    try{
       statement = connection.creatStatement();
       resultset = statement.executeQuery("your query here");
       if(resultset.last()){
          return resultset.getRow();
       } else {
           return 0; //just cus I like to always do some kinda else statement.
       }
    } catch (Exception e){
       System.out.println("Error getting row count");
       e.printStackTrace();
    }
    return 0;
}

5
2018-05-24 04:54



तो आप गिनती पाने के लिए सिर्फ एक पूरी क्वेरी निष्पादित करते हैं? बेहतर रूप से COUNT क्वेरी को वापस करने के लिए SQL क्वेरी को बेहतर रूप से संपादित करें - George Birbilis


आपका फ़ंक्शन किसी परिणामसेट के आकार को वापस कर देगा, लेकिन इसके कर्सर को अंतिम रिकॉर्ड के बाद सेट किया जाएगा, इसलिए पहले (), पहले () या पिछले () से पहले कॉल करके इसे रीवाइंड किए बिना आप अपनी पंक्तियां पढ़ने और रीवाइंडिंग करने में सक्षम नहीं होंगे विधियां केवल परिणाम के साथ काम नहीं करेंगे परिणाम (आपको वही अपवाद मिलेगा जो आप अपने दूसरे कोड खंड में प्राप्त कर रहे हैं)।


2
2017-10-25 08:20





अधिकतर ड्राइवर केवल परिणाम का समर्थन करते हैं - इसलिए अंतिम, पहले से पहले विधि आदि समर्थित नहीं हैं।

पहला दृष्टिकोण उपयुक्त है यदि आप एक ही लूप में डेटा भी प्राप्त कर रहे हैं - अन्यथा परिणामसेट पहले से ही पुनरावृत्त हो चुका है और इसका पुन: उपयोग नहीं किया जा सकता है।

ज्यादातर मामलों में पंक्तियों को लाने के बिना पंक्तियों की संख्या प्राप्त करने की आवश्यकता होती है। पंक्ति गणना को खोजने के लिए परिणाम सेट के माध्यम से डेटा को संसाधित करने के समान ही है। इसके बजाए एक और गिनती (*) क्वेरी करना बेहतर है।


2
2017-10-25 08:22



कुछ डेटाबेस सिस्टम पर एक चुनिंदा गिनती (*) क्वेरी करना बहुत धीमा हो सकता है, इसलिए शायद टीएस को परिणामसेट के आकार को जानने की आवश्यकता को दूर करने का एक तरीका मिलना चाहिए। - Mark Rotteveel
मुझे पूरा यकीन है कि SQL सर्वर जेडीबीसी ड्राइवर रिवाइंडेबल परिणाम सेट का समर्थन करता है? यह तैयार कथन को सही ढंग से शुरू करने का मामला है ... और मैं @ मार्ककोटेवेवेल से सहमत हूं, केवल पंक्ति गणना प्राप्त करने के लिए दो प्रश्न जारी करना घातक हो सकता है। यदि इसकी वास्तव में आवश्यकता है, तो आप हमेशा एक जोड़ सकते हैं count(*) over (partition by 1) विंडो फ़ंक्शन, भले ही यह बड़े परिणाम सेट के लिए भी धीमा हो सकता है ... - Lukas Eder