2009-11-06 50 views
0

我試圖按不同字段升序和降序對數據進行排序。但是,我有4個領域我有不同的MySQL的PDO語句(8個查詢總數):減少僅在ORDER BY字段名稱不同的mysql語句

$stmt1 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field1 DESC"); 
$stmt2 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field1 ASC"); 
$stmt3 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field2 DESC"); 
$stmt4 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field3 ASC"); 
$stmt5 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field3 DESC"); 
$stmt6 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field3 ASC"); 
$stmt7 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field4 DESC"); 
$stmt8 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field4 ASC"); 

基於輸入,我挑選合適的語句和綁定並執行它。

if ($sortcode == 1){ 
    $stmt1->bindParam(':categ', $categ, PDO::PARAM_STR); 
    $stmt1->execute(); 
    $fetched = $stmt1->fetchAll(PDO::FETCH_ASSOC); 
} else if ($sortcode == 2){ 
    $stmt2->bindParam(':categ', $categ, PDO::PARAM_STR); 
    $stmt2->execute(); 
    $fetched = $stmt2->fetchAll(PDO::FETCH_ASSOC); 
} else if ($sortcode == 3){ 
    $stmt3->bindParam(':categ', $categ, PDO::PARAM_STR); 
    $stmt3->execute(); 
    $fetched = $stmt3->fetchAll(PDO::FETCH_ASSOC); 
} 
//repeat the block 5 more times, for a total of 8 

這看起來並不正確。由於select語句僅在字段名稱和desc/asc中有所不同,是否有更好的方法來獲取$sortcode並壓縮後面的代碼?

我想我可以更具體地說出這個問題:有沒有一種方法我可以有一個單一的語句/單個pdo語句動態地綁定字段名稱和asc/decs?

回答

4

使用關聯數組來保存預處理語句。

你的輸入是一個列和一個排序方法,對不對?因此,通過編寫查詢:

$columns = array("field1", "field2", "field3", "field4"); 
$orders = array("asc", "desc"); 
$queries = array(); 
foreach($columns as $col) { 
    $queries[$column] = array(); 
    foreach ($orders as $order) { 
    $queries[$column][$order] = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY $column $order"); 
    } 
} 

現在,查找正確的查詢,你並不需要一些合成的代碼 - 你只需直接尋找柱和秩序。

要查詢查詢,而不是讓用戶輸入1-8中的數字,請讓他們輸入一個列和一個訂單。想象一下,列在變量$ col中,而順序在$ ord中。只要說$查詢[$ col] [$ ord]。

如果由於某種原因您必須使用數字(爲什麼?),那麼您需要一個略有不同的策略。在這種情況下,您將按照的數字存儲查詢

$columns = array("field1", "field2", "field3", "field4"); 
$orders = array("asc", "desc"); 
$queries = array(); 
$i = 0; 
foreach($columns as $col) { 
    foreach ($orders as $order) { 
    $i = $i + 1; 
    $queries[$i] = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY $column $order"); 
    } 
} 

換句話說,你應該根據你打算如何查找它們來存儲查詢。

+0

+1它很容易添加排序列,並且沒有列號 - yikes – Fedearne 2009-11-06 19:55:43

+0

這是一個好主意,但是**它不能解決仍然有8個不同pdo語句的大問題。因此,對於每個選項,當涉及到綁定時間時,我仍然需要調用那個與衆不同的命名查詢並進行綁定和執行。所以主代碼(我上面的8個塊)仍然是相同的,沒有減少。儘管這不是我所要求的,但儘管如此, – Chris 2009-11-06 20:13:30

+0

我已編輯回覆,提供一些進一步的解釋,說明它如何解決您的問題。 – novalis 2009-11-06 20:43:39

1

您可以按列號進行訂購,可以對其進行參數設置。如果您在select子句中指定了列,那麼以這種方式使用ORDER BY通常會更清晰。我不確定ASC/DESC是否可以參數化,但是...

+0

我可以使用列名還是列號? – Chris 2009-11-06 19:41:14

0

您可以始終動態構建查詢。將地圖存儲在$sortcode和查詢欄中的SELECT * FROM tabname WHERE categ=:categ部分之間,根據$sortcode獲取正確的列名並添加ORDER BY ...部分。

+0

通過字符串連接構建查詢的一部分,就像您建議要淡化pdo的安全功能一樣? 'categ'是用戶提供的數據,其餘的不是,因爲它是我的。我的猜測是不,但只是想仔細檢查。 – Chris 2009-11-06 19:48:35

+0

您添加到查詢中的所有內容都是您的代碼,而不是用戶輸入。 – 2009-11-06 21:27:12