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