如何使用准备好的PDO语句设置ORDER BY参数?

时间:2010-03-30 02:01:19

标签: php mysql pdo

我在SQL的ORDER BY部分使用params时遇到问题。它不会发出任何警告,但不打印任何内容。

$order = 'columnName';
$direction = 'ASC';

$stmt = $db->prepare("SELECT field from table WHERE column = :my_param ORDER BY :order :direction");
$stmt->bindParam(':my_param', $is_live, PDO::PARAM_STR);
$stmt->bindParam(':order', $order, PDO::PARAM_STR);
$stmt->bindParam(':direction', $direction, PDO::PARAM_STR);
$stmt->execute();

:my_param有效,但不是:order:direction。是不是在内部正确转义?我是不是直接插入SQL?像这样:

$order = 'columnName';
$direction = 'ASC';

$stmt = $db->prepare("SELECT * from table WHERE column = :my_param ORDER BY $order $direction");

PDO::PARAM_COLUMN_NAME常数还是等价?

谢谢!

8 个答案:

答案 0 :(得分:47)

是的,您不会直接将其插入SQL中。当然,有一些预防措施。 脚本中的每个运算符/标识符都必须是硬编码的,如下所示:

$orders=array("name","price","qty");
$key=array_search($_GET['sort'],$orders);
$order=$orders[$key];
$query="SELECT * from table WHERE is_live = :is_live ORDER BY $order";

方向相同。

请注意bindParam没有转义,因为不需要转义。它具有约束力。

答案 1 :(得分:12)

我认为你不能:

  • order by子句中使用占位符
  • 绑定列名:您只能绑定值 - 或变量,并在预准备语句中注入其值。

答案 2 :(得分:9)

可能ORDER BY子句中使用预准备语句,遗憾的是,您需要传递名称列的命令,并且必须设置PDO_PARAM_INT类型。

在MySQL中,您可以使用此查询获取列的顺序:

SELECT column_name, ordinal_position FROM information_schema.columns 
WHERE table_name = 'table' and table_schema = 'database'

PHP代码:

$order = 2;

$stmt = $db->prepare("SELECT field from table WHERE column = :param ORDER BY :order DESC");
$stmt->bindParam(':param', $is_live, PDO::PARAM_STR);
$stmt->bindParam(':order', $order, PDO::PARAM_INT);
$stmt->execute();

答案 3 :(得分:4)

我认为您不能将ASC / DESC作为准备好的声明的一部分,但您可以使用该列。

 order 
    by 
       case :order
           when 'colFoo' then colFoo
           when 'colBar' then colBar
           else colDefault
       end
       $direction

由于ASC / DESC只有两个可能的值,您可以轻松地验证它们并在它们之间作为硬编码值进行选择。

您也可以使用ELT(FIELD(,,,,),,,,,)函数,但随后排序将始终以字符串形式完成,即使它是一个数字列。

答案 4 :(得分:0)

不幸的是,我猜你无法用准备好的陈述来做到这一点。 这将使其无法缓存,因为不同的列可能具有可以使用特殊排序策略进行排序的值。

使用标准转义创建查询并直接执行。

答案 5 :(得分:0)

可能。您可以在“order by”子句中使用数字而不是字段名称。这是一个从1开始的数字,它是查询中字段名称的顺序。并且您可以为ASC或DESC连接一个字符串。例如 “从tab1顺序选择col1,col2,col3?”+ strDesc +“limit 10,5”。 strDesc =“ASC”/“DESC”。

答案 6 :(得分:-2)

如果我没有完全弄错,帕斯卡是对的 PDO中唯一可能的绑定是值的绑定,就像使用':my_param'参数一样 但是,在以下方面没有造成任何伤害:

$stmt = $db->prepare("SELECT field from table WHERE column = :my_param ORDER BY ".$order ." ".$direction);
$stmt->bindParam(':my_param', $is_live, PDO::PARAM_STR);
$stmt->execute();

唯一需要注意的是$order$direction的正确转义,但由于您手动设置它们并且没有通过用户输入设置它们,我想你们都是集。

答案 7 :(得分:-2)

创建if-else条件 如果(ascCondion)然后绑定值,但硬编码ORDER BY columnName ASC
否则
绑定值但硬编码ORDER BY COlumnName DESC