解析for循环中的无效游标状态

时间:2014-05-11 17:00:11

标签: java ms-access for-loop pivot sqlexception

我有一个从数据库中检索其值的方法。当我在ms访问中尝试时,我传递的查询工作正常。错误发生在"结果[rowCount] [i] = rs.getString(i + 1);"这是我的方法的完整代码。

private String[][] connectToDB2(String query) throws ClassNotFoundException{
        String[][] results = null;
        try {

                Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
                String db = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=D:/EACA_AgroVentures1.accdb";
                conn = DriverManager.getConnection(db);
                stmt = conn.prepareStatement(query,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
                ResultSet rs = stmt.executeQuery();
                ResultSetMetaData rsm = rs.getMetaData();

                int columns = rsm.getColumnCount();
                int rows = getRowCount(rs);
                if(query.contains("PIVOT") ){
                    System.out.println(query);
                    rows=getRowCount2(query);

                }else if(query.contains("GROUP BY")){
                    rows = getRowCount(query);
                }
                //int rows = rs.getFetchSize();
                int rowCount = 0;
                results = new String[rows][columns];
                System.out.println(rows+" PIVOT "+columns);


                System.out.println("Entering While Loop");
                do{    
                   System.out.println(rowCount);
                   if(rowCount == rows){
                        return results;
                   }else{
                        for(int i = 0; i < columns; i++){
                            System.out.println("Running While Loop");
                            rs.next();
                            results[rowCount][i] = rs.getString(i+1);
                            System.out.println(rowCount+",,,,"+i+" = "+results[rowCount][i]);
                        }
                     rowCount++;
                   }
                }while(rs.isAfterLast()==true);
                System.out.println("Exiting While Loop");
                rs.getStatement().close();
                conn.close();

        } catch (SQLException ex) {
            Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
            ex.printStackTrace();
        }
        return results;
    }

提前谢谢。

编辑:我已将ResultSet.TYPE_SCROLL_SENSITIVE更改为ResultSet.TYPE_FORWARD_ONLY,然后将do-while更改为while。所有结果都已显示但是带有arrayIndexOutOfBoundsException。我该如何解决这个问题?以下是我更新的代码。

private String[][] connectToDB2(String query) throws ClassNotFoundException{
        String[][] results = null;
        try {

                Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
                String db = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=D:/EACA_AgroVentures1.accdb";
                conn = DriverManager.getConnection(db);
                stmt = conn.prepareStatement(query,ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);
                ResultSet rs = stmt.executeQuery();
                ResultSetMetaData rsm = rs.getMetaData();

                int columns = rsm.getColumnCount();
                int rows = getRowCount(rs);
                if(query.contains("PIVOT") ){
                    System.out.println(query);
                    rows=getRowCount2(query);

                }else if(query.contains("GROUP BY")){
                    rows = getRowCount(query);
                }
                //int rows = rs.getFetchSize();
                int rowCount = 0;
                results = new String[rows][columns];
                System.out.println(rows+" PIVOT "+columns);

                System.out.println("Entering While Loop");
                while (rs.next()) { 
                    for(int i = 0; i < columns; i++){
                        System.out.println("Running While Loop");
                        results[rowCount][i] = rs.getString(i+1);
                        System.out.println(rowCount+",,,,"+i+" = "+results[rowCount][i]);
                     }
                     rowCount++;
                }

                System.out.println("Exiting While Loop");
                rs.getStatement().close();
                conn.close();

        } catch (SQLException ex) {
            Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
            ex.printStackTrace();
        }
        return results;
    }

这是错误

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 41
    at com.eaca.MainFrame.connectToDB2(MainFrame.java:224)
    at com.eaca.MainFrame.attendanceView(MainFrame.java:469)
    at com.eaca.MainFrame.access$600(MainFrame.java:53)
    at com.eaca.MainFrame$ChangeTab.stateChanged(MainFrame.java:536)
    at javax.swing.JTabbedPane.fireStateChanged(JTabbedPane.java:416)
    at javax.swing.JTabbedPane$ModelListener.stateChanged(JTabbedPane.java:270)
    at javax.swing.DefaultSingleSelectionModel.fireStateChanged(DefaultSingleSelectionModel.java:132)
    at javax.swing.DefaultSingleSelectionModel.setSelectedIndex(DefaultSingleSelectionModel.java:67)
    at javax.swing.JTabbedPane.setSelectedIndexImpl(JTabbedPane.java:616)
    at javax.swing.JTabbedPane.setSelectedIndex(JTabbedPane.java:591)
    at javax.swing.plaf.basic.BasicTabbedPaneUI$Handler.mousePressed(BasicTabbedPaneUI.java:3644)
    at java.awt.Component.processMouseEvent(Component.java:6502)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3320)
    at java.awt.Component.processEvent(Component.java:6270)
27,,,,0 = 23    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4861)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4489)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
    at java.awt.Container.dispatchEventImpl(Container.java:2273)
    at java.awt.Window.dispatchEventImpl(Window.java:2719)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:694)
    at java.awt.EventQueue$3.run(EventQueue.java:692)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:708)
    at java.awt.EventQueue$4.run(EventQueue.java:706)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

2 个答案:

答案 0 :(得分:1)

对于行的每次迭代,您多次调用ResultSet.next() - 每列一次,在for循环内 - 这最终导致异常,因为您尝试移动超过结束它。在一个更普遍的问题上,这是迭代ResultSet的一种尴尬方式。使用传统的while循环可以让您的生活更轻松:

int rowCount = 0;
while (rs.next()) { 
    for(int i = 0; i < columns; i++){
        System.out.println("Running While Loop");
        results[rowCount][i] = rs.getString(i+1);
        System.out.println(rowCount+",,,,"+i+" = "+results[rowCount][i]);
     }
     rowCount++;
}

答案 1 :(得分:1)

当Access数据库引擎使用GROUP BY子句(包括交叉表查询)处理任何查询时,它将返回不可更新的记录集。因此,您无法使用ResultSet.TYPE_SCROLL_SENSITIVEResultSet.TYPE_SCROLL_INSENSITIVE作为resultSetType;您必须使用ResultSet.TYPE_FORWARD_ONLY(这是默认设置)。