像'LIMIT 0,50'这样的字符串可以和命名参数一起使用吗?

时间:2013-07-02 15:53:35

标签: php mysql pdo prepared-statement named-parameters

我正在更新一些旧的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')作为价值工作?
  • 是什么? 使用命名参数的规则,以及它们与...的区别 SQL字符串中的简单变量替换,即旧的mysql_ * 功能可以使用?

关于什么可以和不能用作命名参数,php.net上的PDO页面有点含糊不清,我正在寻找比我发现的更深入的东西:

  • 您必须为要传递给语句的每个值包含唯一参数标记
  • 您不能在预准备语句中两次使用同名的命名参数标记。
  • 您无法将多个值绑定到单个命名参数,例如,SQL语句的IN()子句。

我目前正在使用PHP 5.1.6

3 个答案:

答案 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将起作用。