简体   繁体   English

Java遍历多个SQL查询

[英]java looping through multiple sql queries

I'm trying to loop through multiple sql queries that are executed. 我试图遍历已执行的多个sql查询。 I want to first get all the question information for a certain task and then get the keywords for that question. 我想首先获取某个任务的所有问题信息,然后获取该问题的关键字。 I have three records in my Questions table, but when the while loop at the end of list.add(keyword); 我的Questions表中有3条记录,但是当while循环在list.add(keyword);的末尾时list.add(keyword); is done, it jumps to the SELECT Questions.Question loop (as it should) and then just jumps out and gives me only one record and not the other 2. 完成后,它跳到SELECT Questions.Question循环(应如此),然后跳出并只给我一条记录,而没有给我另外2条记录。

What am I doing wrong? 我究竟做错了什么? Can someone maybe help me fix my code? 有人可以帮我修复我的代码吗? I've thought of doing batch sql executes (maybe that is the solution), but within each while loop, I need information from the previous sql statement, so I can't just do it all at the end of the batch. 我曾考虑过执行批处理sql(也许是解决方案),但是在每个while循环中,我需要来自先前sql语句的信息,所以我不能只在批处理结束时就做所有事情。

SQL Code: SQL代码:

String TaskTopic = eElement.getElementsByTagName("TaskTopic").item(0).getTextContent();

// perform query on database and retrieve results
String sql = "SELECT Tasks.TaskNo FROM Tasks WHERE Tasks.TaskTopic = '" + TaskTopic + "';";
System.out.println("   Performing query, sql = " + sql);
result = stmt.executeQuery(sql);
Document doc2 = x.createDoc();
Element feedback = doc2.createElement("Results");

while (result.next())
{
    String TaskNo = result.getString("TaskNo");
    // perform query on database and retrieve results

    String sqlquery = "SELECT Questions.Question, Questions.Answer, Questions.AverageRating, Questions.AverageRating\n" +
              "FROM Questions\n" +
             "INNER JOIN TaskQuestions ON TaskQuestions.QuestionID = Questions.QuestionID \n" +
             "INNER JOIN Tasks ON Tasks.TaskNo = '" + TaskNo + "';";                                  
    result = stmt.executeQuery(sqlquery);

    while (result.next())
    {
        String Question = result.getString("Question");
        String Answer = result.getString("Answer");
        String AverageRating = result.getString("AverageRating");                                 
        String sqlID = "SELECT QuestionID FROM Questions WHERE Question = '" + Question + "';";
        result = stmt.executeQuery(sqlID);      

        while (result.next())
        {
            String ID = result.getString("QuestionID");
            String sqlKeywords = "SELECT Keyword FROM LinkedTo WHERE QuestionID = '" + ID + "';";
            result = stmt.executeQuery(sqlKeywords);

            while (result.next())
            {
                String keyword = result.getString("Keyword");
                list.add(keyword);
            }
       }
       feedback.appendChild(x.CreateQuestionKeyword(doc2, Question, Answer, AverageRating, list));
    }
}

Why this should be done in SQL 为什么要在SQL中完成

Creating loops is exponentially less efficient than writing a sql query. 与编写sql查询相比,创建循环的效率成倍降低。 Sql is built to pull back this type of data and can plan out how it is going to get this data from the database (called an execution plan). Sql的构建是为了拉回此类数据,并且可以计划如何从数据库中获取此数据(称为执行计划)。

Allowing Sql to do its job and determine the best way to pull back the data instead of explicitly determining what tables you are going to use first and then calling them one at a time is better in terms of the amount of resources you will use, how much time it will take to get the results, code readability, and maintainability in the future. 就您将使用的资源量,如何使用,如何允许Sql来执行其工作并确定最好的方式以拉回数据,而不是显式确定要首先使用的表,然后一次调用它们一次更好。将来要花很多时间才能获得结果,代码可读性和可维护性。

What information you are looking for 您正在寻找什么信息

In the psuedocode you provided, you are using the Keyword , Question , Answer , and AnswerRating values. 在您提供的伪代码中,您正在使用KeywordQuestionAnswerAnswerRating值。 Finding these values should be the focus of the sql query. 查找这些值应该是sql查询的重点。 Based on the code you have written, Question , Answer , and AnswerRating are coming from the Questions table and Keyword is coming from the LinkedTo table, so both of these tables should be available to have data pulled from them. 根据您编写的代码, QuestionAnswerAnswerRating来自Questions表,而Keyword来自LinkedTo表,因此这两个表都应该可用以从中提取数据。

You can note at this point that we have essentially just mapped out what the Select and From portions of your query should look like. 您可以在这一点上注意到,我们基本上已经映射出查询的“ Select和“ From部分的外观。

It also looks like you have a parameter called TaskTopic so we need to include the table Tasks to make sure the correct data is returned. 看起来您有一个名为TaskTopic的参数,因此我们需要包含Tasks表以确保返回正确的数据。 Lastly, the TaskQuestions table is the link between the tasks and the questions. 最后, TaskQuestions表是任务和问题之间的链接。 Now that we know what the query should look like, let's see what the results are using sql syntax. 现在我们知道了查询的外观,让我们看看使用sql语法的结果。

The Code 编码

You did not include the declaration of stmt , but I assume that it is a PreparedStatement. 您没有包括stmt的声明,但我假设它是PreparedStatement。 You can add parameters to a prepared statement. 您可以将参数添加到准备好的语句中。 Notice the ? 请注意? in the sql code? 在SQL代码? The parameters you provide will be added in place of the ? 您提供的参数将代替? . To do this, you should use stmt.setString(1, TaskTopic); 为此,您应该使用stmt.setString(1, TaskTopic); . Note that if there were more than one parameter, you would need to add them in the order that they exists in the sql query (using 1, 2, ...) 请注意,如果有多个参数,则需要按照它们在sql查询中存在的顺序添加它们(使用1、2,...)

SELECT  l.Keyword,
        q.Question,
        q.Answer,
        q.AverageRating
FROM LinkedTo l Inner Join
     Questions q
  on l.questionID = q.QuestionID
Where exists (  Select  1
                From TaskQuestions tq INNER JOIN 
                     Tasks t
                  on tq.TaskNo = t.TaskNo
                Where t.TaskTopic = ?
                and tq.QuestionID = q.QuestionID)

This is one way that you can write the query to return the same results. 这是您可以编写查询以返回相同结果的一种方式。 There are other ways to write this to get what you are looking for. 还有其他方法可以编写此代码以获取所需的内容。

What's Going On? 这是怎么回事?

There are a few things in this query you may not be familiar with. 您可能不熟悉此查询中的一些内容。 First are table aliases. 首先是表别名。 Instead of writing the table name over and over again, you can alias your tables. 您可以为表加上别名,而不必一遍又一遍地写表名。 I used the letter q to represent the Questions table. 我用字母q代表Questions表。 Any time you see q. 任何时候看到q. you should recognize that I am referring to a column from Questions . 您应该认识到我指的是Questions一列。 The q after Questions is what gives the table its alias. Questions后面的q是什么赋予表别名。

Exists Instead of doing a bunch of inner joins with tables that you are not selecting information from, you can use an exists to check if what you are looking for is in those tables. Exists而不是对您没有从中选择信息的表进行一堆内部联接,您可以使用一个存在项来检查您要查找的内容是否在那些表中。 You can continue to do inner joins if you need data from the tables, but if you don't, Exists is more efficient. 如果您需要表中的数据,则可以继续执行内部联接,但是如果不需要,则Exists效率更高。

I suspect you had issues with the query before (and probably the one you provided) because you did not provide any information to join TaskQuestions and Tasks together. 我怀疑您之前(可能是您提供的)查询方面存在问题,因为您没有提供任何信息来将TaskQuestionsTasks一起加入。 That most likely resulted in the duplicates. 那很可能导致重复。 I joined on TaskNo but this may not be the correct column depending on how the tables are set up. 我加入了TaskNo但是根据表的设置,这可能不是正确的列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM