Нельзя ли «вкладывать» запросы ResultSet? или использовать запрос внутри al oop? - PullRequest
0 голосов
/ 27 апреля 2020
public void generateEnumeration() {
        StyledDocument docExam = txtpaneExamGeneration.getStyledDocument();
        StyledDocument docAnsKey = txtpaneAnswerKey.getStyledDocument();

        Connection con = null;
        Statement stmt = null;
        try {
            Class.forName("org.sqlite.JDBC");
            con = DriverManager.getConnection("jdbc:sqlite:sql_items.sqlite");
            stmt = con.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT DISTINCT group_name FROM active_items;");
            int num = numIndex;
            char[] letterArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
            int letterIndex = 0;

            docExam.insertString(docExam.getLength(), "Enumeration - Enumerate the following:\n\n" , null);

            while(rs.next()){
                String groupNameHandler = rs.getString("group_name");

                docExam.insertString(docExam.getLength(), letterArray[letterIndex] + ". " + groupNameHandler + ".\n", null);

                ResultSet rs2 = stmt.executeQuery("SELECT * FROM active_items WHERE group_name = '" + groupNameHandler + "'");
                while(rs2.next()) {
                    String itemNumbering = Integer.toString(num);
                    String ansHandler = rs.getString("item_name");

                    docAnsKey.insertString(docAnsKey.getLength(), itemNumbering + ". ", null);
                    docAnsKey.insertString(docAnsKey.getLength(), ansHandler + "\n", null);

                    num ++; // this is needed to increase the numbering while in the WHILE LOOP
                    numIndex ++; // this is needed to save the last number used after the WHILE LOOP so that it will be continued on the next function
                } // end for ResultSet 2

                letterIndex ++;

            } // end ResultSet 1

            letterIndex = 0;
            docExam.insertString(docExam.getLength(), "\n\n" , null);

        } catch (ClassNotFoundException | SQLException e) {
            System.out.println(e);
        } catch (BadLocationException ex) {
            Logger.getLogger(generateExam.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                con.close();
                stmt.close();
            } catch (SQLException ex) {
                Logger.getLogger(generateExam.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

целью этого кода является создание викторины типа перечисления. Это выведет в 2 JTextPanes, один для docExam и один для docAnsKey

ResultSet rs = stmt.executeQuery("SELECT DISTINCT group_name FROM active_items;"); должен (и это делает, потому что я тестировал на SQLite, и это работает) получить 3 строки из базы данных , Однако выходные данные выглядят так:

docExam:

Enumeration - Enumerate the following

A. Enum question 1 

и

in docAnsKey:

1. CorrectAns1
2. CorrectAns2

, когда в действительности база данных содержит 12 элементов.

Кажется, что while(rs.next()){ выполняется только один раз, поэтому остальная часть кода пропускается. И я не могу найти, где здесь моя ошибка. Может кто-нибудь указать мне на это?

Содержимое базы данных:

item_id --- item_name    --- group_name
1            CorrectAns1     Enum question 1
2            CorrectAns2     Enum question 1
3            CorrectAns3     Enum question 2
4            CorrectAns4     Enum question 2
5            CorrectAns5     Enum question 2
6            CorrectAns6     Enum question 2
7            CorrectAns7     Enum question 2
8            CorrectAns8     Enum question 2
9            CorrectAns9     Enum question 2
10           CorrectAns10    Enum question 2
11           CorrectAns11    Enum question 3
12           CorrectAns12    Enum question 3

1 Ответ

1 голос
/ 27 апреля 2020

После нескольких часов проб и ошибок я пришел к выводу, что ResultSet не может обрабатывать несколько «использований». Поэтому, когда я использовал его для rs2.next(), он забыл данные из rs.next(). Поэтому мой обходной путь - вывести всю 2-ю часть функции из l oop, так как порядок сортировки аналогичен тому, когда я вызываю SELECT DISTINCT group_name FROM active_items; и SELECT * FROM active_items, и не влияет на целостность программы.

окончательный код здесь:

public void generateEnumeration() {
        StyledDocument docExam = txtpaneExamGeneration.getStyledDocument();
        StyledDocument docAnsKey = txtpaneAnswerKey.getStyledDocument();

        Connection con = null;
        Statement stmt = null;
        try {
            Class.forName("org.sqlite.JDBC");
            con = DriverManager.getConnection("jdbc:sqlite:sql_items.sqlite");
            stmt = con.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT DISTINCT group_name FROM active_items;");
            int num = numIndex;
            char[] letterArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
            int letterIndex = 0;

            docExam.insertString(docExam.getLength(), "Enumeration - Enumerate the following:\n\n" , null);

            while(rs.next()){
                String groupNameHandler = rs.getString("group_name");

                docExam.insertString(docExam.getLength(), letterArray[letterIndex] + ". " + groupNameHandler + ".\n", null);

                letterIndex ++;
            }

            ResultSet rs2 = stmt.executeQuery("SELECT * FROM active_items");
            while(rs2.next()) {
                String itemNumbering = Integer.toString(num);
                String ansHandler = rs.getString("item_name");

                docAnsKey.insertString(docAnsKey.getLength(), itemNumbering + ". ", null);
                docAnsKey.insertString(docAnsKey.getLength(), ansHandler + "\n", null);

                num ++; // this is needed to increase the numbering while in the WHILE LOOP
                numIndex ++; // this is needed to save the last number used after the WHILE LOOP so that it will be continued on the next function
            }

            letterIndex = 0;
            docExam.insertString(docExam.getLength(), "\n\n" , null);

        } catch (ClassNotFoundException | SQLException e) {
            System.out.println(e);
        } catch (BadLocationException ex) {
            Logger.getLogger(generateExam.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                con.close();
                stmt.close();
            } catch (SQLException ex) {
                Logger.getLogger(generateExam.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
...