在SQL平台的`order by`子句中进行参数化

时间:2018-12-14 21:17:19

标签: sql

在我看来,有时参数化查询在order by子句中不起作用?

我尝试过mysql; postgres; C#;

例如:

  • php + mysql

    
    $stmt = $conn->prepare("SELECT id, name FROM user order by ? desc");
    $stmt->bind_param("s", $orderby);
    $orderby = "name";
    $stmt->execute();
    

订单被忽略

  • Postgres:

查看此https://github.com/brianc/node-postgres/issues/300

  • .net + mssql:

查看此"Order By" using a parameter for the column name

是否在某处记录了这种情况的标准参考?并在哪个平台上使用Parameterize不支持ORDER BY

2 个答案:

答案 0 :(得分:1)

您将字符串值'name'绑定到sql中的参数。这意味着对于处理的每一行,SQL将看到相同的字符串,即'name'

重点是'name'不会被解释为与列名匹配的文字name,而是已设置或绑定到替换变量{{1}的VARCHAR值'name' }。

在这种情况下,如果您有一个变量?子句,则将有两个(或更多)SQL版本,您可以使用常规的ORDER BY / if选择它们/ then

另一种方法是直接在字符串中连接排序列,而不是使用绑定变量。我强烈建议您这样做,因为这为将来的SQL注入奠定了基础。无论哪种方式,如果将变量输入字符串连接到SQL,请确保已对其进行了充分的清理和检查以避免出现问题。

在PHP中串联起来很简单:

else

另请参见PHP - concatenate or directly insert variables in string(必须纠正,最初使用的语法仅适用于PHP $orderby = "name"; $stmt = $conn->prepare("SELECT id, name FROM user order by ".$orderby." desc"); $stmt->execute(); 命令)。

所有其他与其他数据库(Oracle,MySQL,TSQL等)结合的实现语言(C#,Java等)都将面临相同的问题和解决方案:您必须在SQL中的绑定变量和文字之间进行区分

如果您仍然想使用绑定变量-有一种方法,但是您必须按照以下方式修改sql:

echo

您的实际想法很好(在您的评论中),仍然以某种方式使用绑定变量。现在,我也不再遇到SQL Injection的问题。但是,现在您需要考虑可能发生的每种可能的排序,并在SQL中进行编码。

答案 1 :(得分:1)

准备好的语句中的占位符用于值,而不是ORDER BY或列名的参数。如果您希望动态注入ORDER BY条件,建议您使用您使用的任何语言(PHP)连接:

$orderByCondition = "name";
$stmt = $conn->prepare("SELECT id, name FROM user order by " . $orderByCondition . " desc");
$stmt->execute();

当然,由于您不是直接从用户注入输入,因此实际上不需要使用准备好的语句。