MySQL 带有可变大小变量列表的准备语句
如何在 PHP 中编写每次使用不同数量参数的准备好的 MySQL 语句? 此类查询的一个示例是:
SELECT `age`, `name` FROM `people` WHERE id IN (12, 45, 65, 33)
IN
子句每次运行时都会有不同数量的 id
。
我脑子里有两种可能的解决方案,但想看看是否有更好的方法。
可能的解决方案1 让语句接受100个变量,并用保证不在表中的虚拟值填充其余的变量; 对超过 100 个值进行多次调用。
可能的解决方案2 不要使用准备好的语句; 构建并运行查询,严格检查可能的注入攻击。
How would you write a prepared MySQL statement in PHP that takes a differing number of arguments each time? An example such query is:
SELECT `age`, `name` FROM `people` WHERE id IN (12, 45, 65, 33)
The IN
clause will have a different number of id
s each time it is run.
I have two possible solutions in my mind but want to see if there is a better way.
Possible Solution 1 Make the statement accept 100 variables and fill the rest with dummy values guaranteed not to be in the table; make multiple calls for more than 100 values.
Possible Solution 2 Don't use a prepared statement; build and run the query checking stringently for possible injection attacks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我可以想到几个解决方案。
一种解决方案可能是创建临时表。 将 in 子句中包含的每个参数插入到表中。 然后对临时表进行简单的连接。
另一种方法可能是做这样的事情。
我怀疑,但没有证据,第一个解决方案可能更适合较大的列表,而后者适用于较小的列表。
为了让 @orrd 高兴,这里有一个简洁的版本。
I can think of a couple solutions.
One solution might be to create a temporary table. Do an insert into the table for each parameter that you would have in the in clause. Then do a simple join against your temporary table.
Another method might be to do something like this.
I suspect, but have no proof, that the first solution might be better for larger lists, and the later would work for smaller lists.
To make @orrd happy here is a terse version.
还有
FIND_IN_SET
函数< /a> 其第二个参数是逗号分隔值的字符串:There is also the
FIND_IN_SET
function whose second parameter is a string of comma separated values:不错的 sql 包装器支持绑定到数组值。
IE
decent sql wrappers support binding to array values.
i.e.
请把#2 从桌子上去掉。 准备好的语句是您应该考虑保护自己免受 SQL 注入的唯一方法。
然而,您可以做的是生成一组动态的绑定变量。 即,如果您需要 7 个(或 103 个),则不要制作 100 个。
Please take #2 off the table. Prepared statements are the only way you should consider protecting yourself against SQL injection.
What you can do, however, is generate a dynamic set of binding variables. i.e. don't make 100 if you need 7 (or 103).
我的答案来自: http://bugs.php.net/bug.php? id=43568。
这是我的问题的 mysqli 解决方案。 现在我可以动态地使用任意数量的参数。 它们将与我在数组中的编号相同,或者在本例中,我传递了最后一个查询中的 id(它找到了 email = '[email protected]') 到动态查询,以获取有关每个 id 的所有信息,无论我最终需要多少个。
I got my answer from: http://bugs.php.net/bug.php?id=43568.
This is my working mysqli solution to my problem. Now I can dynamically use as many parameters as I want. They will be the same number as I have in an array or as in this case I am passing the ids from the last query ( which found all the ids where email = '[email protected]') to the dynamic query to get all the info about each of these id no matter how many I end up needing.
如果您仅在
IN
子句中使用整数值,则无需使用 SQL 参数即可动态构建查询。但毫无疑问,解决方案这里是解决这个问题的更通用的方法。
If you're only using integer values in your
IN
clause, there's nothing that argues against constructing your query dynamically without the use of SQL parameters.But without doubt the solution here is the more general approach to this problem.
我今天遇到了类似的问题,我找到了这个主题。 查看答案并在谷歌上搜索,我找到了一个很好的解决方案。
虽然,我的问题有点复杂。 因为我有固定的绑定值和动态的。
这是 mysqli 解决方案。
以及函数makeValuesreferenced:
获取此“知识”的链接:https://bugs.php.net/bug.php?id=49946,PHP 将一个数组附加到另一个数组(不是 array_push 或 +),[PHP]: 错误 -> sprintf() 中的参数太少;、https://www.php.net/manual/en/mysqli-stmt.bind-param.php#89171,PHP 5.3.1 的引用传递问题
I had a similiar problem today and I found this topic. Looking at the answers and searching around the google I found a pretty solution.
Although, my problem is a little bit more complicated. Because I have fixed binding values and dynamic too.
This is the mysqli solution.
And the function makeValuesreferenced:
Links for getting this 'know-how': https://bugs.php.net/bug.php?id=49946, PHP append one array to another (not array_push or +), [PHP]: Error -> Too few arguments in sprintf();, https://www.php.net/manual/en/mysqli-stmt.bind-param.php#89171, Pass by reference problem with PHP 5.3.1