【发布时间】:2013-06-30 02:08:57
【问题描述】:
我正在更新一些旧的 PHP 代码,但遇到了一个我不完全理解的问题。在过去的 mysql_* 函数中,您可以在 SQL 查询中包含一个变量,例如:
$query = "SELECT * FROM table $limit";
在哪里$limit = "LIMIT 0,50";。因此完整的查询是
$query = "SELECT * FROM table LIMIT 0,50";
一切正常。但是,对于 PDO 预准备语句和命名参数,这种类型的简单替换似乎是不可能的,除非您分解限制语句。例如:
$stmt = $conn->prepare('SELECT * FROM table :myLimit');
$stmt->execute(array(':myLimit'=>' LIMIT 0,50'));
导致错误:
错误:SQLSTATE[42000]:语法错误或访问冲突:1064 你 您的 SQL 语法有错误;检查对应的手册 您的 MySQL 服务器版本,以便在“?”附近使用正确的语法在线 1
但如果我将该查询更改为以下内容,以便进一步分解 LIMIT:
$stmt = $conn->prepare('SELECT * FROM table LIMIT :start,:end ');
$stmt->execute(array(':start'=>0,':end'=>50));
效果很好。
- 那么为什么不使用
:myLimit作为命名参数和array(':myLimit'=>' LIMIT 0,50')作为价值工作? - 什么是 使用命名参数的规则,以及它们与 旧 mysql_* 的 SQL 字符串中的简单变量替换 函数可以使用吗?
php.net 上的 PDO 页面在谈到什么可以用作命名参数和不可以用作命名参数时有点模棱两可,我一直在寻找比我发现的更深入的东西:
- 您必须为要传递给语句的每个值包含一个唯一的参数标记
- 您不能在准备好的语句中两次使用同名的命名参数标记。
- 您不能将多个值绑定到单个命名参数,例如 SQL 语句的 IN() 子句。
我目前使用的是 PHP 5.1.6
【问题讨论】:
-
如果我错了,其他人会纠正我,但是当你绑定值时,它基本上会清理它们,因此它只是一个用于比较的值。由于 Limit 是一个保留字,它可能会对其进行清理。
-
没有。占位符只能插入值。不是 sql 关键字。
LIMIT ?,?是可能的,但不能将整个子语句作为单个占位符。 -
@MarcB - 是的,我通过反复试验发现了这一点。是否有任何文档可以解释参数限制的细节? Php.net 似乎掩盖了这一点。
-
准备好的语句不像复制粘贴。它实际上更像是函数的单独参数,准备好的语句就是函数。
-
@Pitchinnate 没有像“消毒”这样的东西,而且 PDO 肯定不会这样做。
标签: php mysql pdo prepared-statement named-parameters