预编译语句中的WHERE IN子句表现出意外行为。

17 浏览
0 Comments

预编译语句中的WHERE IN子句表现出意外行为。

我正在重新编写一些PHP代码,使用PDO来访问数据库,但在使用"WHERE... IN"查询时遇到了问题。

我想根据表单上被选中的项目来从数据库中删除一些内容。列表的长度和内容会有所变化,但是以这个例子来说明,假设是这样的:

$idlist = '260,201,221,216,217,169,210,212,213';

然后查询语句如下:

$query = "DELETE from `foo` WHERE `id` IN (:idlist)";
$st = $db->prepare($query);
$st->execute(array(':idlist' => $idlist));

当我这样做时,只有第一个ID被删除了。(我猜测它会抛弃逗号以及之后的内容。)

我还尝试过将$idlist设为数组,但是那样的话什么都不会被删除。

在PDO预处理语句中,如何正确使用一个项目列表?

0
0 Comments

问题的原因是在使用PDO的预处理语句中,使用WHERE IN子句时,传递参数的方式不正确。在给定的示例中,使用了一个包含数字的数组$arr作为参数,并通过将数组的元素连接成字符串来构建IN子句。

然而,这种方法在实际应用中会导致问题。因为预处理语句中的参数必须是一个数组,而不是一个字符串。因此,代码中的$stm->execute($arr)应该改为$stm->execute([$arr]),将参数作为数组传递给execute方法。

修正后的代码如下所示:

$arr = [1,2,3];
$in  = str_repeat('?,', count($arr) - 1) . '?';
$sql = "SELECT * FROM table WHERE column IN ($in)";
$stm = $db->prepare($sql);
$stm->execute([$arr]);
$data = $stm->fetchAll();

通过将参数传递给execute方法的正确方式,可以解决预处理语句中WHERE IN子句的问题。这样,代码就能够正确地执行查询,并将结果存储在$data变量中。

0
0 Comments

问题的原因是在使用准备好的语句的WHERE IN子句时,无法将值(数字)与控制流逻辑(逗号)混合使用,需要为每个值准备一个占位符。解决方法是使用循环绑定参数,为每个值准备一个占位符。可以使用以下代码实现:

$idlist = array('260', '201', '221', '216', '217', '169', '210', '212', '213');
$questionmarks = str_repeat("?,", count($idlist)-1) . "?";
$stmt = $dbh->prepare("DELETE FROM `foo` WHERE `id` IN ($questionmarks)");
// 循环绑定参数
foreach ($idlist as $key => $value) {
    $stmt->bindParam($key+1, $value);
}
$stmt->execute();

另外,还可以使用以下代码实现占位符的生成:

implode(',', str_split(str_repeat('?', count($idList))));

或者:

implode(',', array_fill(0, count($idList), '?'));

在使用这些方法时,需要确保数组的count大于0。另外,可以通过使用`array_values`函数来确保数组具有数值键。

解决方法还可以通过在HTML中使用复选框来实现。例如:


提交表单后,可以通过`$_POST['foos']`获取一个包含所有选中复选框值的数组。然后可以使用以下代码来生成占位符和执行查询:

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

通过使用`$_POST['foos']`数组中的值,将每个占位符替换为相应的值,并执行查询。这样可以实现预期的功能。

0
0 Comments

问题的原因是使用了循环来执行多个删除操作,这种方法虽然可行,但是效率较低。更好的方法是将所有的删除操作合并成一个查询语句。

解决方法是使用WHERE IN子句来一次性删除多个指定的项。下面是使用WHERE IN子句的代码示例:

$idlist = array('260','201','221','216','217','169','210','212','213');
$placeholders = rtrim(str_repeat('?,', count($idlist)), ',');
$stmt = $dbh->prepare("DELETE FROM `foo` WHERE `id` IN ($placeholders)");
$stmt->execute($idlist);

通过将所有的id放入一个数组中,并使用implode函数将数组转换为逗号分隔的字符串,然后将字符串作为WHERE IN子句的参数传递给查询语句,可以一次性删除多个指定的项。这种方法比使用循环执行多个删除操作更高效。

0