【问题标题】:Delete from with a variable number of arguments使用可变数量的参数删除
【发布时间】:2013-10-21 08:26:16
【问题描述】:

我想在这个查询中使用事务

DELETE FROM tbl WHERE id IN(?, ?, ?)

但 ID 的数量是可变的。 有时我有 2 个,有时是 5 个等等。

我可以用不同的方式重写它,让它接受一个包含所有 ID 的 ? 参数吗?

代码:

$pdo->beginTransaction();
$st = $pdo->prepare('DELETE FROM tbl WHERE id IN(?, ?, ?)');

foreach( ... ){

  $st->execute(array($id1, $id2, $id3));
  // but here I may have only 2 IDs to pass, or 5 etc.
}

$pdo->commit();

【问题讨论】:

    标签: php sqlite pdo transactions


    【解决方案1】:

    你可以这样使用:

    $questionmarks = str_repeat("?,", count($_POST['foos'])-1) . "?";    
    $query = "DELETE from `employee_customeraccount` WHERE `id` IN ($questionmarks)";
    $st = $db->prepare($query);
    

    【讨论】:

    • 谢谢,但我认为你不明白。我只想准备一次查询,所以它不能改变......
    • @Alex 你不能对不同数量的 ID 使用相同的预处理语句。
    • @Alex +1 您只需准备一次。然后为您拥有的每个元素绑定并执行。将所有执行放在一个事务中,您将获得任何 RDBMS 的近乎最佳性能。
    • @LS_dev 你不能任意个占位符准备一次——这就是重点。通常值得阅读问题和 cmets。
    • @YourCommonSense 我知道,但是您可以准备一个占位符并执行任意次数。这个答案与问题没有直接关系,而是一个解决方案!
    【解决方案2】:

    说到你问的“XY问题”,

    我可以用不同的方式重写它,让它接受一个单一的吗?包含所有 ID 的参数?

    没有。

    这也没什么意义 - 多次执行不是必须不惜一切代价追求的事情。

    但说到你面临的真正问题,

    显然可能有一两个解决方案。虽然,就像所有 XY 询问者一样,您忽略了最重要的细节,但我们只能猜测。比如说,你可以保存所有的 id,然后在循环之后但在提交之前一次删除它们。

    或者每次都准备删除。没什么大不了的。

    【讨论】:

      【解决方案3】:

      使用固定数量的参数,例如 DELETE FROM tbl WHERE id IN (?,?,?,?,?, ?,?,?,?,?) 中的 10 个。准备此查询并使用 10 个参数的一部分重复执行它:

      for ($offset = 0; $offset < count($yourIdArray); $offset += 10) {
          $params = array_slice($yourIdArray, $offset, 10);
          if (count($params) < 10)
            $params = array_pad($params, 10, $params[0]);
          $st->execute(...);
      }
      

      最后一组参数只是简单地用一个已经包含在数组中的 ID 填充(没有副作用)。

      (注意:我没有可用的 PHP,也不是 PHP 人。所以将以上内容作为伪代码。)

      我不确定语句/查询中的分块参数方法是否对 Sqlite/PHP 有意义,我不希望有查询/语句缓存或查询/语句准备的高成本。我自己在 Oracle 数据库上使用了这种方法,主要是为了避免“查询/语句缓存污染”,这是由于具有不同数量的参数的查询/语句而导致的。

      【讨论】:

      • 您所说的 DML 查询的查询缓存是什么?
      • Sqlite 甚至不会从这种方法中受益,即使它有一个查询缓存,因为它不是一个“查询”。我会编辑可能会回答。顺便说一句,Oracle 的 JDBC 驱动程序具有语句缓存,这可能不适用于 Sqlite/PHP。见stackoverflow.com/questions/3772038/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-28
      • 2017-08-04
      • 2011-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多