PHP PDO error when using placeholders in the LIMIT clause of a MySQL query [duplicate]

折月煮酒 提交于 2020-01-02 02:35:13

问题


$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());
}

Here I get error:

Query failed: SQLSTATE[42000]: 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 ''5'' at line 1.

The LIMIT :startRow, :numRows has problem in :numRows.

I have tried both $st->bindParam and $st->bindValue, both didn't work.


回答1:


I think the problem is with TBL_MEMBERS I suppose this is a view(subselect). So, if you have product table for example and you want to execute following statement:

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

you will receive following error:

SQL Error (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 'select id, code, name, slug, info from products order by code' at line 1

But if you change query to:

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

this will work.

To summarize, TBL_MEMBERS is a view which should be put in parenthesis and given alias(i my example alias is 'v')




回答2:


I recommend to look at the SQL query text what PDO actually produces. You can do this with help of MySQL's general query log.

Most probably, the formal types of $startRow and/or $numRows are strings, not integers, and resulting query is therefore something like LIMIT '0', '5' (syntax error) instead of LIMIT 0, 5 (correct).

The thing is, even with PDO::PARAM_INT, when the parameter's formal type is not integer (is_int returns false), PDO wraps it in quotes. So, you have to cast parameters to integers before binding them (e.g. using intval):

$st->bindParam(":startRow", intval(trim($startRow)), PDO::PARAM_INT);
$st->bindParam(":numRows", intval(trim($numRows)), PDO::PARAM_INT);



回答3:


I solved it.I Type casted the :numRows placeholder.

$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();

And it worked. I also noticed the ' should be use instead of ".



来源:https://stackoverflow.com/questions/30389723/php-pdo-error-when-using-placeholders-in-the-limit-clause-of-a-mysql-query

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!