我正在编写一个从数据库中获取记录的程序。我想基于3个变量(studentID,firstName和/或lastname)创建动态查询。这是我的java代码,它返回记录:
result = statement.executeQuery("SELECT * FROM student "
+ "WHERE (studentID = "
+ getStudentId() + " AND " + getStudentId() + " <> 0)"
+ " OR (firstName = '"
+ getFirstName() + "' AND '" + getFirstName() + "' IS NOT NULL)"
+ " OR (lastName = '"
+ getLastName() + "' AND '" + getLastName() + "' IS NOT NULL)");
我希望搜索根据存在的变量返回模糊到具体的结果。目前,如果studentID是唯一提供的字段,则返回该单个记录,或者如果studentID不存在但firstName为,则返回firstName的所有记录(如果仅存在变量,则返回lastName)。不起作用的是,如果我提供firstName和lastName,它将返回所有带有firstName的记录,而不管记录的姓氏如何,以及所有带有lastName的记录,无论名字是什么。示例firstName =“Bill”和lastName =“Jackson”:
1 Bill Hader
2 Steve Jackson
3 Bill Jackson
4 Bill Stewart
5 Denise Jackson
6 Wendy Jackson
7 Bill Matthews
我想弄清楚的是,如果我提供特定条件,例如firstName和lastName,如何获取包含指定的名字和姓氏的特定记录。
答案 0 :(得分:1)
A)这应该可以解决问题:
String query = "SELECT * FROM student WHERE (studentID=? OR ?=0)
AND (firstName=? OR ? IS NULL)
AND (lastName =? OR ? IS NULL)";
ps.setInt(1,getStudentID());
ps.setString(2,getFirstName());
ps.setString(3,getFirstName());
result ps.executeQuery();
请注意,逻辑与您发布的内容相反。在您的代码中,如果studentId
为0
且firstName
为空,则您有:
(studentID=0 AND 0<>0) OR (firstName='null' OR null IS NOT NULL)
是false
。相反,您需要指定
(studentID=0 OR 0=0) AND (firstName='null' OR null IS NULL)
B)如果你想要Java中的条件逻辑:
String query = "SELECT * FROM student WHERE (";
if (getStudentId()!=0) query+="studentID=? AND";
if (getFirstName()!=null) query+="firstName=? AND";
if (getLastName ()!=null) query+="lastName=? AND";
query+=" 1=1)";
PreparedStatement ps = connection.prepare(query);
if (getStudentId()!=0) ps.setInt(1,getStudentID());
if (getFirstName()!=null) ps.setString(2,getFirstName());
if (getLastName ()!=null) ps.setString(3,getFirstName());
result ps.executeQuery();
答案 1 :(得分:0)
因此,假设您的标准为0,'Bill'和'Jackson',这是您将要执行的查询:
select *
from student
where
(studentID = 0 and 0 <> 0)
or (firstName = 'Bill' and 'Bill' is not null)
or (lastName = 'Jackson' and 'Jackson' is not null)
where
条款中有三个条件。第一个(再次,假设你输入0)将不匹配任何东西。第二个将匹配firstName
为'Bill'的所有记录。第三个将匹配lastName
为'杰克逊'的所有记录。由于您的条件由or
运算符连接,因此结果集(查询结果)将是所有匹配集的并集,因此任何firstName
为'Bill'或其lastName
的记录是'杰克逊',因此你所有的样本记录。如果您想将此限制为只有一个名字和姓氏,请将or
更改为and
并简化查询:
select *
from student
where
firstName = 'Bill'
and lastName = 'Jackson'
您似乎试图在单个where子句中构建太多逻辑。现在,怎么办呢?让我们单独留出studentID
字段一分钟,所以我们只想匹配确切的名字(如果提供了一个)和确切的姓氏(如果有的话)。我们可以这样做:
select *
from student
where
(firstName = ? or ? is null)
and (lastName = ? or ? is null)
最后,您似乎想要的另一个条件是,如果提供学生ID,我们会将结果限制为仅该ID。我们可以这样做:
select *
from student
where
(studentID = ? and ? <> 0)
or (
(firstName = ? or ? is null)
and (lastName = ? or ? is null)
)
为简单起见,假设我们始终返回与给定学生ID匹配的行,即使名字或姓氏不匹配也是如此。 (因此运行参数1,'比尔','杰克逊'将产生两个记录)。如果您想要使用studentID
删除任何与所有三个条件都不匹配的记录,请将查询更改为:
select *
from student
where
(studentID = ? or ? = 0)
and (
(firstName = ? or ? is null)
and (lastName = ? or ? is null)
)
Here's a SQLFiddle展示它是如何运作的。
正如其他人所提到的,请学习如何在Java中使用参数化查询。这并不难。