SELECT id, content, date
FROM comment
WHERE post = ?
ORDER BY date DESC
LIMIT ?, ?
使用 PDO(我使用的是具有 Apache 2.2.21、PHP 最高至 5.3.6 和 MySQL 5.5.9 的 MAMP 2.0.5(预处理语句,如果我更改查询
LIMIT 0, 10
它有效。
我在MySQL的错误中看到这是以前版本中的错误,但我无法理解这是否仍有待修复。
如果这仍然是一个问题,有没有办法以另一种方式选择行范围?
法典:
$comments = $db->prepare($query);
/* where $db is the PDO object */
$comments->execute(array($post, $min, $max));
问题是:
$comments = $db->prepare($query);
/* where $db is the PDO object */
$comments->execute(array($post, $min, $max));
PDOStatement::execute(( 的手册页说(强调我的(:
因此,参数
input_parameters
具有尽可能多的元素的值数组 正在执行的 SQL 语句中的绑定参数。所有值均为 被视为PDO::P ARAM_STR。
您的参数将作为字符串插入,因此最终的 SQL 代码如下所示:
LIMIT '0', '10'
这是一种特殊情况,MySQL不会转换为数字,而是触发解析错误:
mysql> SELECT 1 LIMIT 0, 10;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)
mysql> SELECT 1 LIMIT '0', '10';
ERROR 1064 (42000): 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
文档要说什么:
LIMIT
子句可用于约束行数 由SELECT
语句返回。LIMIT
采用一个或两个数字 参数,它们必须是非负整数常量,具有 这些例外情况:
在预准备语句中,可以使用 ? 占位符标记指定
LIMIT
参数。在存储程序中,可以使用整数值例程参数或局部变量指定
LIMIT
参数。
您的选择包括:
逐个绑定参数,以便设置类型:
$comments->bindParam(1, $post, PDO::PARAM_STR); $comments->bindParam(2, $min, PDO::PARAM_INT); $comments->bindParam(3, $min, PDO::PARAM_INT);
不要将这些值作为参数传递:
$query = sprintf('SELECT id, content, date FROM comment WHERE post = ? ORDER BY date DESC LIMIT %d, %d', $min, $max);
禁用模拟准备(MySQL 驱动程序有一个错误/功能,将使其引用数字参数(:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
您可以声明特定属性来解决问题。
$dbh->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );
另一个答案说明了它是如何工作的。默认情况下,PDO只是模拟准备,并且由于您以静默方式绑定变量,而不设置类型,PDO默认将它们视为字符串。SQL中的字符串必须用引号和转义 - 因此在LIMIT子句中有引号和语法错误。当使用本机预准备语句时,数据库可以设法整理出适当的类型。