2009-12-07 68 views
0

我有一個簡單的SQL查詢,方法匹配任何SQL字符串

SELECT * FROM phones WHERE manu='$manuf' AND price BETWEEN $min AND $max 

的問題是,所有的變量域的連接字段有時會是空的,所以我需要一種方法來使它們匹配它們各自的字段在空的情況下可以採取的任何值。我試圖

$min=$_REQUEST['min_price']; 
$max=$_REQUEST['max_price']; 
$manuf=$_REQUEST['manufact']; 
if (empty($min)){ 
    $min=0;} 
if (empty($max)){ 
    $max=900000;} 
if (empty($manuf)){ 
    $manuf='*';} 

這對於數字字段工作正常(雖然我不喜歡手動設置限制這樣的),但我無法弄清楚如何獲得文本字段通用匹配。我認爲*會這樣做,因爲它匹配所有的行名,但顯然不是。有人知道怎麼做嗎?

+1

那不是SQL代碼 –

+0

'空'是什麼意思?一個空字符串或NULL? –

回答

1

如果我是你,我會將整個SQL切成部分,並處理WHERE語句。

事端,如:

sql = "SELECT * FROM phones WHERE 1=1 " 
if (not empty($manu)) 
    sql = sql + ' AND manu = "$manu"' 
... 

問候。

+0

如果我是你,我會避免像這樣一起動態地構建SQL ... – MatBailie

+0

是的,但我想我們大家都知道SQL注入(以後發佈)以及如何避免它們。如果有人是懶惰的程序員,沒有工具可以改變這一點。 – ATorras

+0

公平點,但我一直處理懶惰的程序員,我的工作的一部分是儘量減少他們的影響;) – MatBailie

1

我猜你想讓它成爲一個「過濾器」類型的查詢,允許參數是可選的?你可以這樣做:

SELECT 
    * 
FROM 
    Phones 
WHERE 
    (manu = $manu OR manu IS NULL) 
    AND (min = $min OR min IS NULL) 
    AND (max = $max OR max IS NULL) 

添加或與空選項(你可以把它空字符串或其他),您可以傳遞任何參數進行篩選。

您可以將其與上面的內容結合使用,檢查最小/最大值併爲BETWEEN子句提供默認值。

+1

我認爲他的意思是(價格> = $ min或$ min IS NULL)AND(價格<= $ max或$ max IS NULL)。但請,請考慮SQL注入。要麼準備語句,要麼至少使用mysql_real_escape_string()來轉義輸入! –

1

我傾向於通過更改SQL中的邏輯並傳遞NULL參數或具有特定值的參數來執行此操作。

WHERE manu='$manuf' AND price BETWEEN $min AND $max 

=>

WHERE 
    (manu='$manuf' OR '$manuf' = '*') -- Check for "special value" 
    AND (price >= $min OR $min IS NULL) -- Check for NULL 
    AND (price <= $max OR $max IS NULL) -- Check for NULL 
+1

注:我說我傳入參數,你正在建立一個動態執行的字符串。正如其他人所說的那樣,由於SQL注入攻擊,這是非常糟糕的做法。最好使用允許參數化的方法。 – MatBailie

+0

總是存在權衡 - 由於使用OR,您的建議會受到性能方面的影響,這會破壞可控性。可以處理SQL注入。 –

+0

+1 Java擁有PreparedStatement對象,它將幫助您防止SQL注入。這張表可能會幫助你實現這個目標:http://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet – ATorras

0

也許像...

SELECT * FROM phones 
WHERE manu = coalesce(?, manu) 
AND price >= coalesce(?, price) 
AND price <= coalesce(?, price) 

然後在參數傳遞,而不是直接投入變量(不知道怎麼做,在PHP關閉我的頭頂)。