如何将 pdo 的准备语句用于 order by 和 limit 子句?
我想使用一个准备好的语句,其中传入的参数用于 ORDER BY
和 LIMIT
子句,如下所示:
$sql = 'SELECT * FROM table ORDER BY :sort :dir LIMIT :start, :results';
$stmt = $dbh->prepare($sql);
$stmt->execute(array(
'sort' => $_GET['sort'],
'dir' => $_GET['dir'],
'start' => $_GET['start'],
'results' => $_GET['results'],
)
);
But $stmt->fetchAll (PDO::FETCH_ASSOC);
不返回任何内容。
有人可以指出我做错了什么吗?能做到吗?如果没有,我应该参考什么来获取可以使用参数的完整子句列表?
I want to use a prepared statement in which the passed-in parameters are for the ORDER BY
and LIMIT
clauses, like so:
$sql = 'SELECT * FROM table ORDER BY :sort :dir LIMIT :start, :results';
$stmt = $dbh->prepare($sql);
$stmt->execute(array(
'sort' => $_GET['sort'],
'dir' => $_GET['dir'],
'start' => $_GET['start'],
'results' => $_GET['results'],
)
);
But $stmt->fetchAll(PDO::FETCH_ASSOC);
returns nothing.
Can someone point out what's the wrong thing I am doing? Can it be done? If not,what should I reference for a complete list of clauses where parameters can be used?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
使用后:
我收到消息:
因此,当您使用数组执行时,它会将您的输入视为字符串,这对于 LIMIT 来说不是一个好主意
After using :
I got the message :
So, when you use an array for execute, it consider your inputs as string which is not a good idea for LIMIT
准备好的语句允许 DBMS 在实际执行针对您提供的参数的查询之前为您的查询生成查询计划。更改 ORDER BY 的字段需要不同的查询计划,因为以不同的方式对数据进行排序可能会极大地影响 DBMS 选择获取数据的方式:例如,某些索引在一种情况下可能会有所帮助,但不在另一个。因此,
ORDER BY
字段应构成传递给prepare()
方法的 SQL 字符串的一部分,而不是在execute( )
。至于
LIMIT
子句,尚不清楚其参数是否会影响查询计划,因此这些参数可能会在稍后绑定,这可能取决于您的 DBMS。根据这个SO答案应该允许它。Prepared statements allow the DBMS to generate a query plan for your query before actually executing the query for your supplied parameters. Changing the fields for
ORDER BY
requires a different query plan, because ordering you data in different ways can drastically affect how the DBMS might choose to get the data: for instance, certain indexes may help in one case but not in another. For this reason theORDER BY
fields should form part of the SQL string passed into theprepare()
method, rather than being bound to the query prior toexecute()
.As for the
LIMIT
clause, it's not clear whether its parameters would affect the query plan, so these may be bound later, possibly depending upon your DBMS. According to this SO answer it should be allowed.您不能绑定参数来指定语言关键字或字段名称 - 它必须替换文字。因此,我认为你的极限值很好,但你的排序依据却不行。最好手动替换字符串中的 sort 和 dir。转义它们,但不要使用数据库工具来执行此操作,因为它们不是字符串文字。基本上确保不存在特殊字符。
You can't bind a parameter to specify a language keyword or a field name - it has to be replacing a literal. Therefore, your limit values I think are fine, but your order by is not. It will be best for you to manually replace sort and dir in the string. Escape them but don't use the DB tools to do so, since they aren't string literals. Basically ensure no special characters are present.
虽然这个问题相当老了,但我认为它可能仍然很有趣。对我来说,在我
PDO::PARAM_INT
结合使用之后,就像intval()
将变量内容转换为整数值之前所建议的那样,它的相关部分代码如下所示:
不使用
intval()
我还收到了错误语法错误或访问冲突:1064 您的 SQL 语法中有错误;检查与您的 MySQL 服务器版本相对应的手册,了解在第 1 行“0”、10”附近使用的正确语法Although this question is rather old, I think it might still be of interest. For me it worked after I
PDO::PARAM_INT
like suggested beforeintval()
The relevant part of the code then looks like this:
Without using
intval()
I also received the error Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''0', 10' at line 1