2013-03-13 85 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