我试图遍历执行的多个sql查询。我想首先获取某个任务的所有问题信息,然后获取该问题的关键字。我的问题表中有三条记录,但是当list.add(keyword);
结束时的while循环完成后,它会跳转到SELECT Questions.Question
循环(应该这样),然后跳出来只给我一个一个记录,而不是其他2.
我做错了什么?有人可以帮我修改我的代码吗?我已经想过要执行批处理sql(也许这就是解决方案),但是在每个while循环中,我需要来自前一个sql语句的信息,所以我不能在结束时完成所有操作。批次。
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));
}
}
答案 0 :(得分:1)
为什么要在SQL
中完成此操作创建循环的效率比编写SQL查询要低得多。构建Sql是为了回退这种类型的数据,并可以规划如何从数据库中获取这些数据(称为执行计划)。
允许Sql完成其工作并确定撤回数据的最佳方法,而不是先明确确定要使用哪些表,然后一次调用一个表,这样就可以提供更多的资源。使用,将来需要多长时间才能获得结果,代码可读性和可维护性。
您正在寻找哪些信息
在您提供的伪代码中,您使用的是Keyword
,Question
,Answer
和AnswerRating
值。查找这些值应该是sql查询的重点。根据您编写的代码,Question
,Answer
和AnswerRating
来自Questions
表,Keyword
来自LinkedTo
} table,因此这两个表都应该可以从中获取数据。
您现在可以注意到,我们基本上只是确定了查询的Select
和From
部分应该是什么样的。
看起来您还有一个名为TaskTopic
的参数,因此我们需要包含表Tasks
以确保返回正确的数据。最后,TaskQuestions
表是任务和问题之间的链接。现在我们知道查询应该是什么样子了,让我们看一下使用sql语法的结果。
守则
您没有包含stmt
的声明,但我认为它是PreparedStatement。您可以将参数添加到预准备语句中。请注意sql代码中的?
?您提供的参数将被添加到?
。为此,您应该使用stmt.setString(1, TaskTopic);
。请注意,如果有多个参数,则需要按照它们在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)
这是您可以编写查询以返回相同结果的一种方法。还有其他方法来写这个来获得你想要的东西。
接下来会怎样?
您可能不熟悉此查询中的一些内容。首先是表别名。您可以为表格添加别名,而不是一遍又一遍地编写表格名称。我用字母q代表Questions
表。每当您看到q.
时,您都应该认识到我指的是Questions
中的一列。 Questions
之后的q是表格的别名。
Exists
您可以使用exists来检查您要查找的内容是否在这些表中,而不是使用您未从中选择信息的表进行大量内部联接。如果您需要表格中的数据,您可以继续进行内部联接,但如果您不这样做,Exists
会更有效率。
我怀疑您之前的查询存在问题(可能是您提供的问题),因为您没有提供任何信息来加入TaskQuestions
和Tasks
。这很可能导致重复。我加入TaskNo
,但这可能不是正确的列,具体取决于表的设置方式。