【问题标题】:SELECT query not working with IN using prepared statementSELECT 查询不适用于使用准备好的语句的 IN
【发布时间】:2018-06-22 08:06:16
【问题描述】:

有人可以帮我获取 SELECT 查询 (2)。下面上班?

此字符串用于两个 SELECT 语句:

$seller_items = ('6','9','12','13','14','15','16','17','18','19','20','22','23','24','25','26','28','27','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','53','54','55','57','58','59','60','62','63','64','65','61','67','56','69','70','74','73','75','78','80','76','72','95','94','101','102','71','103','2','104','4','81','21','10','11','3','79','5','8','7','97','93','96','98');

(1)。此 SELECT 查询运行良好:

if ($stmt = $mysqli->prepare("SELECT info FROM items WHERE item_id IN $seller_items AND active = ?")){
$stmt->bind_param("s",$active); 

(2)。此 SELECT 查询不起作用:

if ($stmt = $mysqli->prepare("SELECT info FROM items WHERE item_id IN ? AND active = ?")){
$stmt->bind_param("ss",$seller_items,$active);

我认为将变量放在 SELECT 查询本身可能会破坏预准备语句的目的。

我可以使 IN 谓词与未准备好的语句一起正常工作。这是我遇到问题的准备好的声明。

提前谢谢你。

【问题讨论】:

  • 您不能在 SQL 中参数化 IN 运算符。
  • 在 MSSQL 中,参数化值数组的方法是将其作为表值参数传递,并与它进行 JOIN。我假设 MySQL 有类似的东西。否则,创建并插入到临时表中。
  • @Dai - 感谢您提供的信息。我很感激。 :)
  • @Mike - 感谢您提供信息和链接。我很感激。 :)

标签: php mysql prepared-statement


【解决方案1】:

正如@Dai 所说,IN 不能只用一个变量进行参数化。当然可以使用一系列参数来完成,但它们的数量是固定的。 prepare 语句的想法是,值的插入预期在相同的位置、相同数量的参数和相同的类型。

如果 IN 中的参数数量是固定的,类似这样的工作:

$a=[1,2,3];
$s=$mysqli->prepare("SELECT id FROM users WHERE role_id IN (?,?,?)");
$s->bind_param('iii',$a[0],$a[1],$a[2]);
$s->execute();
$s->bind_result($id);
$c=[];
while($s->fetch()){
  $c[]=$id;
}
var_dump($c);

也许这不是您要寻找的答案,但如果不知道变量的数量,最好在原始 SQL 命令中插入内爆数组字符串。

$a=[1,2,3];
$b="('".implode("','",$a)."')";
$s=$mysqli->prepare("SELECT id FROM users WHERE role_id IN {$b}");
$s->execute();
$s->bind_result($id);
$c=[];
while($s->fetch()){
  $c[]=$id;
}
var_dump($c);

【讨论】:

  • 一种选择是拥有大量预定义的占位符并将NULL 放入未使用的占位符中。我假设 MySQL 查询预处理器会优化它,例如WHERE foo IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,) -> WHERE foo IN (1,2,3,4,NULL,NULL,NULL,NULL,NULL,NULL,etc)
  • 是的,可以。然而bind_param 也变得难以实现,它需要一堆虚拟变量。
  • @Carlos H. - 你为我省去了很多麻烦。谢谢。 :) 另一个问题可以吗? {$b} 效果很好。该方法是否会妨碍 SELECT 查询的安全性?
  • @Harvey 这一切都取决于如何捕获和清理这些值以避免包括单引号。如果他们这样做(例如爱尔兰姓氏),他们需要被转义。如果他们确定数字应该不是问题。实际上,无论是否准备报表,它都是开发人员尽职调查清理用户输入的地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-27
  • 2018-12-11
  • 2020-06-06
  • 1970-01-01
  • 2011-09-07
  • 2020-12-08
相关资源
最近更新 更多