Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

JDBC का उपयोग करके संग्रहीत कार्यविधि से *सब कुछ* वापस कैसे प्राप्त करें

जब हम JDBC में एक संग्रहीत कार्यविधि निष्पादित करते हैं तो हमें शून्य या अधिक "परिणाम" की एक श्रृंखला वापस मिलती है। फिर हम CallableStatement#getMoreResults() पर कॉल करके उन "परिणामों" को क्रमिक रूप से संसाधित कर सकते हैं . प्रत्येक "परिणाम" में हो सकता है

  • डेटा की शून्य या अधिक पंक्तियां जिन्हें हम ResultSet . के साथ पुनर्प्राप्त कर सकते हैं वस्तु,
  • एक डीएमएल स्टेटमेंट के लिए एक अपडेट काउंट (INSERT, UPDATE, DELETE) जिसे हम CallableStatement#getUpdateCount() के साथ पुनः प्राप्त कर सकते हैं। , या
  • एक त्रुटि जो SQLServerException को फेंकती है।

"समस्या 1" के लिए अक्सर समस्या यह होती है कि संग्रहीत कार्यविधि SET NOCOUNT ON; से प्रारंभ नहीं होती है और परिणाम सेट बनाने के लिए चयन करने से पहले एक डीएमएल कथन निष्पादित करता है। डीएमएल के लिए अद्यतन गणना पहले "परिणाम" के रूप में लौटा दी जाती है, और डेटा पंक्तियां "इसके पीछे फंस जाती हैं" जब तक हम getMoreResults को कॉल नहीं करते हैं ।

"अंक 2" अनिवार्य रूप से एक ही समस्या है। त्रुटि होने से पहले संग्रहीत प्रक्रिया "परिणाम" (आमतौर पर एक चयन, या संभवतः एक अद्यतन गणना) उत्पन्न करती है। त्रुटि को बाद के "परिणाम" में वापस कर दिया जाता है और जब तक हम getMoreResults का उपयोग करके इसे "पुनर्प्राप्त" नहीं करते तब तक कोई अपवाद नहीं होता है ।

कई मामलों में केवल SET NOCOUNT ON; . जोड़कर समस्या से बचा जा सकता है संग्रहीत प्रक्रिया में पहले निष्पादन योग्य कथन के रूप में। हालांकि, संग्रहीत कार्यविधि में परिवर्तन हमेशा संभव नहीं होता है और तथ्य यह रहता है कि सब कुछ प्राप्त करने के लिए संग्रहीत कार्यविधि से वापस हमें getMoreResults . को कॉल करते रहने की आवश्यकता है जब तक, जैसा कि जावाडोक कहता है:

There are no more results when the following is true: 

     // stmt is a Statement object
     ((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1))

यह काफी सरल लगता है, लेकिन हमेशा की तरह, "शैतान विवरण में है", जैसा कि निम्नलिखित उदाहरण द्वारा दिखाया गया है। SQL सर्वर संग्रहीत कार्यविधि के लिए ...

ALTER PROCEDURE dbo.TroublesomeSP AS
BEGIN
    -- note: no `SET NOCOUNT ON;`
    DECLARE @tbl TABLE (id VARCHAR(3) PRIMARY KEY);

    DROP TABLE NonExistent;
    INSERT INTO @tbl (id) VALUES ('001');
    SELECT id FROM @tbl;
    INSERT INTO @tbl (id) VALUES ('001');  -- duplicate key error
    SELECT 1/0;  -- error _inside_ ResultSet
    INSERT INTO @tbl (id) VALUES ('101');
    INSERT INTO @tbl (id) VALUES ('201'),('202');
    SELECT id FROM @tbl;
END

... निम्नलिखित जावा कोड सब कुछ वापस कर देगा ...

try (CallableStatement cs = conn.prepareCall("{call dbo.TroublesomeSP}")) {
    boolean resultSetAvailable = false;
    int numberOfResultsProcessed = 0;
    try {
        resultSetAvailable = cs.execute();
    } catch (SQLServerException sse) {
        System.out.printf("Exception thrown on execute: %s%n%n", sse.getMessage());
        numberOfResultsProcessed++;
    }
    int updateCount = -2;  // initialize to impossible(?) value
    while (true) {
        boolean exceptionOccurred = true; 
        do {
            try {
                if (numberOfResultsProcessed > 0) {
                    resultSetAvailable = cs.getMoreResults();
                }
                exceptionOccurred = false;
                updateCount = cs.getUpdateCount();
            } catch (SQLServerException sse) {
                System.out.printf("Current result is an exception: %s%n%n", sse.getMessage());
            }
            numberOfResultsProcessed++;
        } while (exceptionOccurred);

        if ((!resultSetAvailable) && (updateCount == -1)) {
            break;  // we're done
        }

        if (resultSetAvailable) {
            System.out.println("Current result is a ResultSet:");
            try (ResultSet rs = cs.getResultSet()) {
                try {
                    while (rs.next()) {
                        System.out.println(rs.getString(1));
                    }
                } catch (SQLServerException sse) {
                    System.out.printf("Exception while processing ResultSet: %s%n", sse.getMessage());
                }
            }
        } else {
            System.out.printf("Current result is an update count: %d %s affected%n",
                    updateCount,
                    updateCount == 1 ? "row was" : "rows were");
        }
        System.out.println();
    }
    System.out.println("[end of results]");
}

... निम्न कंसोल आउटपुट का उत्पादन:

Exception thrown on execute: Cannot drop the table 'NonExistent', because it does not exist or you do not have permission.

Current result is an update count: 1 row was affected

Current result is a ResultSet:
001

Current result is an exception: Violation of PRIMARY KEY constraint 'PK__#314D4EA__3213E83F3335971A'. Cannot insert duplicate key in object '[email protected]'. The duplicate key value is (001).

Current result is a ResultSet:
Exception while processing ResultSet: Divide by zero error encountered.

Current result is an update count: 1 row was affected

Current result is an update count: 2 rows were affected

Current result is a ResultSet:
001
101
201
202

[end of results]



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. मैं एक परिणाम सेट में SQL सर्वर के सभी डेटाबेस में सभी तालिकाओं को कैसे सूचीबद्ध करूं?

  2. SQL सर्वर:गलत संस्करण 661 संलग्न करें

  3. SQL सर्वर - पंक्तियों को अल्पविराम से अलग की गई सूची में शामिल करें

  4. एसक्यूएल ऑपरेशंस स्टूडियो (एसक्यूएलओपीएस) क्या है?

  5. कुल फ़ंक्शन के बिना एसक्यूएल सर्वर में पिवट क्वेरी कैसे बनाएं?