您不能IN
为此使用谓词,因为IN
只知道如何比较=
并且您需要进行不同的比较以处理 NULL。
MySQL 有一个非标准的空安全相等运算符<=>
,它知道 NULL=NULL 为真,而 NULL = 'RED' 为假。
如果您使用 MySQL 以外的其他东西,您的 RDBMS 可能支持IS [NOT] DISTINCT
类似谓词的标准 SQL 语法。
我测试了以下,它的工作原理:
$arr = array('C050101','RED', 'C070104', NULL);
$sql = "SELECT `id`, `WebTitle`, `StockCode` FROM `stock`
WHERE (`StockCode`, `StockVariant`) <=> (?, ?)
OR (`StockCode`, `StockVariant`) <=> (?, ?)";
$stockstmt = $pdo->prepare($sql);
if ($stockstmt === false) { die(print_r($pdo->errorInfo(), true)); }
$status = $stockstmt->execute($arr);
if ($status === false) { die(print_r($stockstmt->errorInfo(), true)); }
我将把它留给您如何构建谓词列表。
回复您的评论:
不建议使用文字字符串“NULL”来表示缺失或不适用的值。这就是 NULL 在 SQL 中的用途。
如果您想要一个使构建谓词更加动态的函数,请尝试以下操作:
function lookformultiplethings(array $arr)
{
global $pdo;
$where = array();
$values = array();
foreach ((array) $arr as $term) {
$where[] = '('
. join(',', array_map(function ($col) {return "`$col`";}, array_keys($term)))
. ') <=> ('
. join(',', array_fill(0,count($term),'?'))
. ')';
$values = array_merge($values, array_values($term));
}
$sql = "SELECT `id`, `WebTitle`, `StockCode` FROM `stock` ";
if ($where) {
$sql .= "WHERE " . join(' OR ', $where);
}
$stockstmt = $pdo->prepare($sql);
if ($stockstmt === false) { die(print_r($pdo->errorInfo(), true)); }
$status = $stockstmt->execute($values);
if ($status === false) { die(print_r($stockstmt->errorInfo(), true)); }
print_r($stockstmt->fetchAll());
}
lookformultiplethings(array(
array('StockCode' => 'C050101', 'StockVariant' => 'RED'),
array('StockCode' => 'C070104', 'StockVariant' => 'NULL'),
));
请注意,您传递的数组的键是合法的列名。也就是说,除非您根据真实列的白名单对其进行验证,否则不要让用户输入设置列名。