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

时间:2022-04-25 19:25:25

In essence, I have a value that I have to call a couple times in my SQL query. Thus, is it possible to reuse the same named placeholder in the statement e.g. SELECT :Param FROM Table WHERE Column = :Param, then simply bindValue(":Param"), and have the value be there for both :Params?

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

3 个解决方案

#1


18  

PDO::prepare states that "you cannot use a named parameter marker of the same name twice in a prepared statement", so I guess that's a no then.

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

#2


2  

You can if you set PDO::ATTR_EMULATE_PREPARES = true.

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

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

例如。 $ connection-> setAttribute(PDO :: ATTR_EMULATE_PREPARES,true);.

If you're using Laravel you can set this in an options array in config/database.php. e.g. PDO::ATTR_EMULATE_PREPARES => true

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

#3


1  

Apart from reuse, the main issue here is that you are trying to dynamically change col names.

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

This answer posted by an anonymous user on http://php.net/manual/en/pdo.prepare.php :

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

To those wondering why adding quotes to around a placeholder is wrong, and why you can't use placeholders for table or column names:

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

There is a common misconception about how the placeholders in prepared statements work: they are not simply substituted in as (escaped) strings, and the resulting SQL executed. Instead, a DBMS asked to "prepare" a statement comes up with a complete query plan for how it would execute that query, including which tables and indexes it would use, which will be the same regardless of how you fill in the placeholders.

关于预处理语句中的占位符如何工作存在一个常见的误解:它们不是简单地替换为(转义的)字符串,而是执行生成的SQL。相反,DBMS要求“准备”一个语句会提供一个完整的查询计划,说明它将如何执行该查询,包括它将使用哪些表和索引,无论您如何填充占位符,这些表和索引都是相同的。

The plan for "SELECT name FROM my_table WHERE id = :value" will be the same whatever you substitute for ":value", but the seemingly similar "SELECT name FROM :table WHERE id = :value" cannot be planned, because the DBMS has no idea what table you're actually going to select from.

“SELECT name FROM my_table WHERE id =:value”的计划将与“:”替换相同,但是看似相似的“SELECT name FROM:table WHERE id =:value”无法计划,因为DBMS我不知道你真正要从哪个表中选择。

Even when using "emulated prepares", PDO cannot let you use placeholders anywhere, because it would have to work out what you meant: does "Select :foo From some_table" mean ":foo" is going to be a column reference, or a literal string?

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

When your query is using a dynamic column reference, you should be explicitly white-listing the columns you know to exist on the table, e.g. using a switch statement with an exception thrown in the default: clause.

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

#1


18  

PDO::prepare states that "you cannot use a named parameter marker of the same name twice in a prepared statement", so I guess that's a no then.

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

#2


2  

You can if you set PDO::ATTR_EMULATE_PREPARES = true.

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

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

例如。 $ connection-> setAttribute(PDO :: ATTR_EMULATE_PREPARES,true);.

If you're using Laravel you can set this in an options array in config/database.php. e.g. PDO::ATTR_EMULATE_PREPARES => true

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

#3


1  

Apart from reuse, the main issue here is that you are trying to dynamically change col names.

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

This answer posted by an anonymous user on http://php.net/manual/en/pdo.prepare.php :

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

To those wondering why adding quotes to around a placeholder is wrong, and why you can't use placeholders for table or column names:

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

There is a common misconception about how the placeholders in prepared statements work: they are not simply substituted in as (escaped) strings, and the resulting SQL executed. Instead, a DBMS asked to "prepare" a statement comes up with a complete query plan for how it would execute that query, including which tables and indexes it would use, which will be the same regardless of how you fill in the placeholders.

关于预处理语句中的占位符如何工作存在一个常见的误解:它们不是简单地替换为(转义的)字符串,而是执行生成的SQL。相反,DBMS要求“准备”一个语句会提供一个完整的查询计划,说明它将如何执行该查询,包括它将使用哪些表和索引,无论您如何填充占位符,这些表和索引都是相同的。

The plan for "SELECT name FROM my_table WHERE id = :value" will be the same whatever you substitute for ":value", but the seemingly similar "SELECT name FROM :table WHERE id = :value" cannot be planned, because the DBMS has no idea what table you're actually going to select from.

“SELECT name FROM my_table WHERE id =:value”的计划将与“:”替换相同,但是看似相似的“SELECT name FROM:table WHERE id =:value”无法计划,因为DBMS我不知道你真正要从哪个表中选择。

Even when using "emulated prepares", PDO cannot let you use placeholders anywhere, because it would have to work out what you meant: does "Select :foo From some_table" mean ":foo" is going to be a column reference, or a literal string?

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

When your query is using a dynamic column reference, you should be explicitly white-listing the columns you know to exist on the table, e.g. using a switch statement with an exception thrown in the default: clause.

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