2013-03-13 25 views
0

我在写一个从数据库中获取记录的程序。我想创建一个基于3个变量(studentID,firstName和/或lastname)的动态查询。这里是一个返回记录我的Java代码:带有Java的动态SQL查询

 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 = “比尔” 和lastName = “杰克逊”:

1比尔·哈德 2史蒂夫杰克逊 3比尔杰克逊 4比尔斯图尔特 5丹尼斯杰克逊 6温迪杰克逊 7个比尔马修斯

我我试图弄清楚的是,如果我提供的具体条件,如firstName和lastName如何获得包含指定的名字和姓氏的特定记录。

+2

首先,我建议您阅读准备好的语句:http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html – NPE 2013-03-13 11:48:12

+3

当然,必须有'xkcd'引用(这看起来特别适合你的例子):http://xkcd.com/327/ – NPE 2013-03-13 11:49:18

+0

你的叙述描述了一个需要条件逻辑的情况。但是,您的代码中没有任何内容。 – 2013-03-13 11:57:22

回答

0

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(); 

注意,逻辑是你已经发布的正好相反。在你的代码,如果studentId0firstName为空,您有:

(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(); 
+0

谢谢。我不知道我在找什么叫准备好的声明。我正在从oracle的网站上读到这个。 – user1957901 2013-03-13 12:30:16

0

因此,假设你的标准是0,“比尔”和“杰克逊”,这是查询您将执行:

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是'Jackson',因此是您的所有样本记录。如果你想限制这只是一个名字和姓氏,改变你的orand和简化查询:

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。我们能够做到这一点,通过使用这样的:

select * 
from student 
where 
    (studentID = ? and ? <> 0) 
or (
     (firstName = ? or ? is null) 
    and (lastName = ? or ? is null) 
) 

对于纯朴的缘故,这是假定我们总是返回的行匹配给定的学生证,即使第一个名字或姓氏不匹配。 (所以用参数1运行'Bill','Jackson'将产生两条记录)。如果你不是想用studentID删除不符合以上三个标准的任何记录,查询改成这样:

select * 
from student 
where 
    (studentID = ? or ? = 0) 
and (
     (firstName = ? or ? is null) 
    and (lastName = ? or ? is null) 
) 

Here's a SQLFiddle展示它是如何工作。

正如其他人所提到的,请学习如何在Java中使用参数化查询。这并不难。

+0

谢谢!我已经学习了大约一个月,编程不是我的专长,但我很欣赏所有这些帮助。 – user1957901 2013-03-13 12:31:56