我正在更新一些旧的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')
作为价值工作?关于什么可以和不能用作命名参数,php.net上的PDO页面有点含糊不清,我正在寻找比我发现的更深入的东西:
我目前正在使用PHP 5.1.6
答案 0 :(得分:7)
为什么不使用:myLimit作为命名参数和数组(':myLimit'=>'LIMIT 0,50')作为值工作?
因为预先准备的陈述仅适用于数据
使用命名参数有哪些规则,它们与旧的mysql_ *函数可以使用的SQL字符串中的简单变量替换有何不同?
规则很简单:您可以为仅数据
使用(任一类型的)参数我目前正在使用PHP 5.1.6
曼。你知道,你升级有点晚了。大约十年左右。
您不能在预准备语句中两次使用同名的命名参数标记。
在现代版本中你可以。
您不能将多个值绑定到单个命名参数,例如,SQL语句的IN()子句。
这是真的。再次因为[native] prepared语句仅用于数据文字
答案 1 :(得分:0)
绑定值时,除了要检查的值之外,您只能包含一个值而不是查询的任何部分。
绑定值用于防止查询操作,因此如果您可以更改查询或将额外的mysql命令添加到绑定参数中,那么这将取消绑定值的整个点
例如,您可以绑定名称或数字以检查某些内容是否等于该值,您无法绑定条件
答案 2 :(得分:-3)
从我所知道的(无法找到文档),绑定检查输入的类型,并确定是否需要引用:整数不需要引用,但字符串可以引用。所以它会看'Limit 0,50'并看到它是一个字符串,然后引用它。那当然是行不通的。如果要将$ limit用作变量,则将其添加到查询字符串中,而不是尝试绑定它。否则,:start /:end将起作用。