在MySQL查询的LIMIT子句中使用占位符时出现PHP PDO错误

时间:2015-05-22 06:25:45

标签: php mysql pdo

$sql = "SELECT sql_calc_found_rows * FROM members".
       " ORDER BY username LIMIT :startRow, :numRows";

try {
    $st = $conn->prepare($sql);
    $st->bindParam(":startRow", $startRow, PDO::PARAM_INT);
    $st->bindParam(":numRows", $numRows, PDO::PARAM_INT);
    $st->execute();
} catch (PDOException $e) {
    die("Query failed: " . $e->getMessage());
}

我收到错误:

  

查询失败:SQLSTATE [42000]:语法错误或访问冲突:1064 SQL语法中有错误;查看与您的MySQL服务器版本对应的手册,以获得正确的语法,以便在'' 5'''在第1行。

LIMIT :startRow, :numRows中的:numRows存在问题。

我已经尝试了$st->bindParam$st->bindValue,两者都没有效果。

3 个答案:

答案 0 :(得分:0)

我认为问题出在TBL_MEMBERS上 我想这是一个视图(subselect)。 因此,如果您有产品表,并且您想要执行以下语句:

select sql_calc_found_rows * from select id, code, name, slug, info from products order by code

您将收到以下错误:

  

SQL错误(1064):您的SQL语法中有错误;检查与您的MySQL服务器版本相对应的手册,以获得正确的语法,以便在附近使用'选择ID,代码,名称,slug,产品订单中的信息'在第1行

但是如果您将查询更改为:

select sql_calc_found_rows * from (select id, code, name, slug, info from products) v order by code

这将有效。

总结一下, TBL_MEMBERS是一个视图,应放在括号中并给出别名(我的例子别名是' v')

答案 1 :(得分:0)

我建议查看PDO实际生成的SQL查询文本。您可以借助MySQL的general query log

来帮助您完成此任务

最有可能的是,$startRow和/或$numRows的正式类型是字符串,而不是整数,因此生成的查询类似于LIMIT '0', '5'(语法错误)而不是{{1 (正确)。

即使使用LIMIT 0, 5,当参数的正式类型不是整数(is_int返回PDO::PARAM_INT)时,PDO也会将其包装在引号中。因此,您必须在绑定它们之前将参数转换为整数(例如,使用intval):

false

答案 2 :(得分:-2)

我解决了它。我输入了:numRows占位符。

$numRows=(int)$numRows; $sql = 'SELECT sql_calc_found_rows * FROM ' . TBL_MEMBERS .'ORDER BY'. $order .'LIMIT :startRow,:numRows'; try { $st = $conn->prepare($sql); $st->bindValue(":startRow", $startRow, PDO::PARAM_INT); $st->bindValue(":numRows", $numRows, PDO::PARAM_INT); $st->execute();

它有效。我还注意到应该使用'而不是"