所以我有四个菜单选项(产品、位置、课程类型和类别),所有这些都可以为空(使用JSF编写,但这与此问题无关,因为这是一个SQL问题)。
菜单选择将向托管bean发送用户选择的变量,并使用准备好的语句使用用户选择的菜单信息(如果有)搜索数据库表。
如果用户将菜单项留空,则应搜索所有内容。
如果用户留下1个或2个或3个带有信息的菜单项,并使其他一个为空,则应相应地进行搜索。
我的问题是如何在不使用大量if / then语句的情况下完成这项工作,而是将其附加到适当的SQL语句中?
还是有更好的SQL语句可以做到这一点?
我在Java中使用了一个预准备语句。
我尝试过这个:
菜单选择将向托管bean发送用户选择的变量,并使用准备好的语句使用用户选择的菜单信息(如果有)搜索数据库表。
如果用户将菜单项留空,则应搜索所有内容。
如果用户留下1个或2个或3个带有信息的菜单项,并使其他一个为空,则应相应地进行搜索。
我的问题是如何在不使用大量if / then语句的情况下完成这项工作,而是将其附加到适当的SQL语句中?
还是有更好的SQL语句可以做到这一点?
我在Java中使用了一个预准备语句。
我尝试过这个:
if (product != null && location != null && courseType != null && category != null) {
pstmt = conn.prepareStatement("select * FROM Courses WHERE "
+ "product = ? "
+ "and location = ? "
+ "and courseType = ? "
+ "and category = ?");
pstmt.setString(1, product);
pstmt.setString(2, location);
pstmt.setString(3, courseType);
pstmt.setString(4, category);
} else if (product == null && location != null && courseType != null && category != null) {
pstmt = conn.prepareStatement("select * FROM Courses WHERE "
+ "location = ? "
+ "and courseType = ? "
+ "and category = ?");
pstmt.setString(1, location);
pstmt.setString(2, courseType);
pstmt.setString(3, category);
}
等等,对于每一种1为空而其他位置不为空的情况我必须重复这样16次?肯定有更聪明的方法(可以使用一个SQL语句或者只用几个Java if/else语句)。
感谢Luiggi Mendoza!我的代码现在是这样工作的:
pstmt = conn.prepareStatement("select * FROM Courses WHERE "
+ "(product = ? or ? is null) "
+ "and (location = ? or ? is null) "
+ "and (courseType = ? or ? is null)"
+ "and (category = ? or ? is null)");
pstmt.setString(1, product);
pstmt.setString(2, product);
pstmt.setString(3, location);
pstmt.setString(4, location);
pstmt.setString(5, courseType);
pstmt.setString(6, courseType);
pstmt.setString(7, category);
pstmt.setString(8, category);
rset = pstmt.executeQuery();
更新:我不得不在另一个MySQL数据库中使用 = "" 而不是 is null(可能是不同的版本或其他原因)。
NULL
,而是使用默认值,比如'0'
或者'EMPTY'
(或者其他针对NULL
的默认值)。 - Luiggi Mendoza