我想使用这样的查询:
$sql = "SELECT `name` FROM `table` WHERE `id` IN (?)";
和bind数组
$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.
问题变成了我们有一个空数组。使用简单的in,我可以在这种情况下将通配符替换为null。但我必须做什么,如果我没有在(?)和空数组?
热点是使用NOT IN (?)
与空数组
问题变成了我们有一个空数组
那是一个很有趣的问题,我花了一些时间来研究。
在朋友的帮助下进行了一些非常有趣的讨论后,我得出结论,如果数组为空,则将NULL
传递到IN()语句中。它做出了非常明智的行为,并且不会使查询失败。
但是,还有一个问题没有解决:
虽然IN(NULL)
返回FALSE,似乎相当明智,NOT IN(NULL)
返回…假了!所以,你要小心这种说法。
对于我自己的实现,我使用条件查询构建作为解决方案,仅在非空数组的情况下添加整个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
问题的建议。