具有可变大小变量列表的 MySQL 预准备语句

2022-08-30 17:10:44

您将如何在PHP中编写准备好的MySQL语句,每次都采用不同数量的参数?此类查询的示例如下:

SELECT `age`, `name` FROM `people` WHERE id IN (12, 45, 65, 33)

该子句每次运行时将具有不同的 s 数。INid

我心中有两种可能的解决方案,但想看看是否有更好的方法。

可能的解决方案 1使语句接受 100 个变量,并用保证不在表中的虚拟值填充其余变量;对超过 100 个值进行多次调用。

可能的解决方案 2不要使用预准备语句;构建并严格运行查询检查,以防可能遭受注入攻击。


答案 1

我可以想到几个解决方案。

一种解决方案可能是创建一个临时表。为 in 子句中的每个参数执行插入到表中。然后对临时表执行简单的联接。

另一种方法可能是做这样的事情。

$dbh=new PDO($dbConnect, $dbUser, $dbPass);
$parms=array(12, 45, 65, 33);
$parmcount=count($parms);   // = 4
$inclause=implode(',',array_fill(0,$parmcount,'?')); // = ?,?,?,?
$sql='SELECT age, name FROM people WHERE id IN (%s)';
$preparesql=sprintf($sql,$inclause);  // = example statement used in the question
$st=$dbh->prepare($preparesql);
$st->execute($parms);

我怀疑,但没有证据,第一种解决方案可能更适合较大的列表,而后者适用于较小的列表。


为了让@orrd在这里感到高兴的是一个简洁的版本。

$dbh=new PDO($dbConnect, $dbUser, $dbPass);
$parms=array(12, 45, 65, 33);
$st=$dbh->prepare(sprintf('SELECT age, name FROM people WHERE id IN (%s)',
                          implode(',',array_fill(0,count($parms),'?'))));
$st->execute($parms);


答案 2

还有一个FIND_IN_SET函数,其第二个参数是逗号分隔值的字符串:

SELECT age, name FROM people WHERE FIND_IN_SET(id, '12,45,65,33')

推荐