有时参数化查询在order by子句中不起作用。
我试过mysql;postgres;C#;
例如:
通过被忽略的命令
看这个https://github.com/brianc/node-postgres/issues/300
参见此"Order By" using a parameter for the column name
是否在某个地方为这种情况提供了标准参考?以及参数化在哪个平台上不适用于ORDER BY**?**
发布于 2018-12-14 21:25:46
将字符串值'name'绑定到sql中的参数。这意味着对于处理的每一行,SQL都会看到相同的字符串,即'name'。
重点是“名称”不是解释为与列名匹配的文字name,而是一个已经设置或绑定到替换变量?的VARCHAR值'name'。
在这种情况下,如果您有一个变量ORDER BY子句,那么您可以使用常规的if / then / else来选择两个(或更多)版本的SQL。
另一种方法是直接连接字符串中的排序列,而不是使用绑定变量。我强烈反对这样做,因为这为今后的SQL注入奠定了基础。无论哪种方式,如果将变量输入字符串连接到SQL中,那么请确保对其进行了充分的清理和检查,以避免出现问题。
PHP中的连接非常简单,如下所示:
$orderby = "name";
$stmt = $conn->prepare("SELECT id, name FROM user order by ".$orderby." desc");
$stmt->execute();还请参阅PHP - concatenate or directly insert variables in string (必须进行更正,最初使用的语法仅适用于echo命令)。
所有其他实现语言(C#、Java等)以及任何数据库(oracle、MySQL、TSQL等)都将面临相同的问题和解决方案:您必须在SQL中区分绑定变量和文字。
如果仍然希望使用bind变量--有一种方法,但是您必须按以下方式修改sql:
SELECT id, name FROM user
ORDER BY CASE ? WHEN 'name' THEN name WHEN 'id' THEN id ELSE NULL END实际上,你(在你的评论中)仍然以某种方式使用绑定变量是很好的想法。现在,我也不再有SQL注入的问题了。但是,现在您需要说明可能发生的每一种可能的排序,并将其编码到SQL中。
发布于 2018-12-14 21:28:37
预准备语句中的占位符用于值,而不是用于按列名排序的参数。如果您希望按条件动态注入订单,我建议在您使用的任何语言中使用级联,在您的情况下使用PHP:
$orderByCondition = "name";
$stmt = $conn->prepare("SELECT id, name FROM user order by " . $orderByCondition . " desc");
$stmt->execute();当然,由于不是直接从用户注入输入,所以实际上不需要使用准备好的语句。
https://stackoverflow.com/questions/53786995
复制相似问题