我想使用这样的查询:
$sql = "SELECT `name` FROM `table` WHERE `id` IN (?)";
并绑定值数组
$sth = $pdo->prepare($sql);
$sth->execute(array(array('1', '2', '4')));
所以,我必须包装PDO。如何实现这种行为并考虑所有陷阱?
必须考虑:
IN(?) with array values;
IN(?) with empty array;
NOT IN(?) with array values;
NOT IN(?) with empty array;
NOT (expr IN (?)) with array values;
NOT (expr IN (?)) with empty.
问题变成我们有一个空数组。简单的我可以在这种情况下将通配符替换为null。但是,如果我没有(?)和空数组,我必须做什么?
热点是NOT IN (?)
使用空数组。
答案 0 :(得分:2)
问题就变成了我们有一个空数组。
这是一个非常有趣的问题,花了我一些时间来调查。
在我朋友的帮助下进行了一些非常有趣的辩论后,我得出结论是将NULL
传递给IN()语句,以防数组为空。它会产生非常明智的行为,并且不会使查询失败。
然而,一个问题仍未解决:
虽然IN(NULL)
返回FALSE并且看起来很合理,NOT IN(NULL)
会再次返回... FALSE!所以,你必须小心这种说法。
对于我自己的实现,我使用条件查询构建作为一种解决方法,仅在非空数组的情况下添加整个NOT IN()
语句。它使逻辑稳固,但代价是额外的代码:
$in = '';
if ($array) {
$in = $db->parse(" AND col NOT IN(?a)", $array);
}
$data = $db->getAll("SELECT * FROM t WHERE name=?s ?p", $name, $in);
(在直接IN的情况下将其与简明陈述进行比较):
$data = $db->getAll("SELECT * FROM t WHERE name=?s AND col IN(?a)", $name, $in);
如果数组为空,则不返回任何行。
所以,我仍然愿意接受有关如何更优雅地解决NOT IN
问题的建议。