PDO参数化查询 - 重用命名占位符?

时间:2010-03-12 10:42:12

标签: php pdo

本质上,我有一个值,我必须在我的SQL查询中调用几次。因此,是否可以在语句中重用相同的命名占位符,例如 SELECT :Param FROM Table WHERE Column = :Param,然后只是bindValue(“:Param”),并且两者都有值:Params?

4 个答案:

答案 0 :(得分:20)

PDO::prepare声明“你不能在准备好的语句中两次使用同名的命名参数标记”,所以我猜那是不行的。

答案 1 :(得分:4)

如果您设置PDO::ATTR_EMULATE_PREPARES = true,则可以。

E.g。 $connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);

如果您使用的是Laravel,可以在options中的config/database.php数组中进行设置。例如PDO::ATTR_EMULATE_PREPARES => true

答案 2 :(得分:2)

除了重用之外,这里的主要问题是您正在尝试动态更改列名。

此答案由匿名用户在http://php.net/manual/en/pdo.prepare.php上发布:

  

有些人想知道为什么在占位符周围添加引号是错误的,   以及为什么不能对表名或列名使用占位符:

     

对占位符的准备方式存在一种常见的误解   陈述有效:它们不能简单地替换为(转义)   字符串,以及生成的SQL。相反,DBMS要求   “准备”一个声明提出了一个完整的查询计划   将执行该查询,包括它将使用哪些表和索引   使用,无论你如何填写,都是一样的   占位符。

     

“SELECT name FROM my_table WHERE id =:value”的计划将是   无论你用什么代替“:价值”,但看似相似   “SELECT name FROM:table WHERE id =:value”无法计划,因为   DBMS不知道您实际要从哪个表中进行选择。

     

即使使用“模拟准备”,PDO也不能让您使用   占位符在任何地方,因为它必须解决你的问题   意思是:“选择:foo来自some_table”意味着“:foo”将成为一个   列引用,或文字字符串?

当您的查询使用动态列引用时,您应该明确地列出您知道存在于表中的列,例如:使用switch语句,并在default:子句中抛出异常。

答案 3 :(得分:0)

许多类似您的查询都可以重写为仅使用一个占位符。

SELECT :Param FROM Table WHERE Column = :Param

将与

相同
SELECT Column FROM Table WHERE Column = :Param

但是有时候并不是那么简单。例如:

SELECT *
FROM my_table
WHERE first_name LIKE :Param
   OR last_name  LIKE :Param
   OR biography  LIKE :Param

在这种情况下,您可以重用参数值,将其存储在交叉连接的派生表中(FROM子句中的子查询):

SELECT t.*
FROM my_table t
CROSS JOIN (SELECT :Param as Param) AS x
WHERE first_name LIKE x.Param
   OR last_name  LIKE x.Param
   OR biography  LIKE x.Param