【问题标题】:How can I use for loop in a IN statement in this situation?在这种情况下,如何在 IN 语句中使用 for 循环?
【发布时间】:2015-02-23 21:16:10
【问题描述】:

我正在使用 for 循环进行选择。我遇到的问题是我在 IN 语句中有多个值。我知道IN(term_1, term_2) 我们需要一个句点来分开每个人。当我使用 for 循环时,我不知道如何附加句点。首先,它在语句括号内而不是在末尾。

<?php
for ($i = 0; $i <= 8; $i++) {
    $stm =$db->prepare("SELECT id FROM sign WHERE term IN (:term_$i) GROUP BY os.user_id order by COUNT(os.user_id) DESC ");

        $stm->bindParam(":term_$i", $search_text[$i]);

        $stm->execute();
    }

?>

【问题讨论】:

  • 你不能那样做。我的意思是,你可以,但你不会在你的 IN 语句中得到一个以上的值。准备好的语句会因 IN 语句而失败。您必须自己构建它并自己逃避价值观。
  • 谢谢!如果我不使用prepare语句或mysqlprepared怎么样,我还没有尝试过。但是我有时间的时候会。谢谢你的时间。
  • @Halfstop - 实际上你可以从一个简单的数组构建准备好的语句,使用trim(str_repeat('?, ', count($values)), ',')IN 语句设置一个简单的? 占位符,然后将值作为绑定传递execute() 中的数组
  • @MarkBaker Right 自己构建它,并将其填充到准备好的语句中。没有办法做到这一点,这不是 hackish。
  • @Halfstop - 但您并没有恢复引用和转义值,仍然使用准备好的语句,那么我的方法有什么奇怪的地方?

标签: php mysql sql for-loop


【解决方案1】:

Prepared 语句占位符只能表示 SINGLE 值。

例如

$foo = '1,2,3';
$db->prepare("SELECT ... WHERE foo in (:foo)");
bind(':foo', $foo);

将创建一个被解释为的查询

SELECT ... WHERE foo IN ('1,2,3');

注意引号 - 你的三个单独的数字现在是一个单值字符串,并且查询运行就像它已经被写入一样:

SELECT ... WHERE foo='1,2,3'

您必须构建动态语句并创建尽可能多的占位符。

foreach ($values as $val) {
     $placeholders[] = '?';
}
$sql = "SELECT ... WHERE foo IN (" . implode(',', $placeholders) . ")";
...prepare/bind other values
$stmt->execute($values);

【讨论】:

  • $sql = sprintf('SELECT ... WHERE foo IN (%s)', implode(',', array_fill(0, count($values), '?')));
【解决方案2】:

恐怕你将不得不以老式的方式来做这件事

$stm ="SELECT id FROM sign WHERE term IN (";
for ($i = 0; $i <= 8; $i++) {
$stm.="'";
$stm.=mysqli_real_escape_string($db,$search_text[$i]);
$stm.="'";
}
$stm.=") GROUP BY os.user_id order by COUNT(os.user_id) DESC ";
$db->query($stm);

【讨论】:

    【解决方案3】:
    <?php
    $sep = ''; $lst = '';
    for ($i = 0; $i <= 8; $i++) {
        $lst .= $sep."'".$search_text[$i]."'";
    }
    $stm =$db->query("SELECT id FROM sign WHERE term IN ($lst) GROUP BY os.user_id order by COUNT(os.user_id) DESC ");
    while ($row = $stm->fetch()) {
        // do something with $row
    }
    ?>
    

    这不使用准备,因此不太安全。您可以尝试使用:term_1, :term_2, ... 创建整个列表,然后对其进行准备然后绑定——这会更安全,也是您应该采取的方向。但希望这个代码示例将向您展示如何动态构建您的 sql。

    (如果您在循环中绑定,请确保使用按引用调用

    foreach ($search_text as $k=>&$v)
        ...bindParam($k, $v);
    

    如果你不这样做,那么你就会遇到问题。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-19
      • 1970-01-01
      • 1970-01-01
      • 2018-09-30
      • 1970-01-01
      • 2019-05-28
      • 1970-01-01
      • 2012-04-08
      相关资源
      最近更新 更多