2009-11-06 94 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