我有一个MySQL列'public',它包含布尔值(也称为tinyint、1或0)。查询时,我通常不关心公共列的值,所以默认情况下我会传递一个下划线(MySQL通配符)。但在某些情况下,我只希望行与"public=0"或"public=1"匹配,所以我用0或1覆盖下划线。这不是我给出的最清晰的解释,所以这里有一些代码:
public function get_hunts($public = '_') {
$sth = $this->_db->prepare("SELECT * FROM hunts WHERE( user_id = :user AND public = :public)");
$sth->bindParam(':user', $this->_id);
$sth->bindParam(':public', $public);
$sth->execute();
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
return $result;
}
//get any result
get_results();
//get only public results
get_hunts(1)
以这种方式绑定下划线(我也尝试过通用通配符%)会导致查询失败。实现这一目标的更好方法是什么?
要使用任何通配符,您需要使用LIKE
比较而不是等于
AND public LIKE :public
否则,您需要采用某种查询生成器方法,根据函数的参数构建WHERE
条件。
public function get_hunts($public = null) {
$where = array(
'user_id = :user'
);
$params = array(
':user' => $this->_id
);
if (null !== $public) {
$where[] = 'public = :public';
$params[':public'] = (boolean) $public;
}
$query = 'SELECT * FROM hunts WHERE ' . implode(' AND ', $where);
$sth = $this->_db->prepare($query);
$sth->execute($params); // same as binding
return $sth->fetchAll(PDO::FETCH_ASSOC);
}
绑定参数仅适用于简单文字,因此不能绑定表和列名(标识符)或IN
子句(文字列表)等内容。
因此,你想要什么是不可能的直接方式。
您真正应该做的是使用不同的查询:
function get_hunts($public=null) {
// assuming hunts.public is defined as NOT NULL
$sql = "SELECT * FROM hunts WHERE user_id=:user";
if ($public!==null) {
$sql .= ' AND public=:public';
}
$sth = $this->_db->prepare($sql);
$sth->bindParam(':user', $this->_id);
if ($public!==null) {
$sth->bindParam(':public', $public, PDO::PARAM_INT);
}
$sth->execute();
return $sth->fetchAll(PDO::FETCH_ASSOC);
}
如果您真的不想使用不同的查询,可以使用带有CASE
表达式的破解解决方案。
SELECT * FROM hunts WHERE user_id=:user
AND public=
CASE :public WHEN 0 THEN 0 WHEN 1 THEN 1 ELSE public END
如果绑定的值不是0或1,则WHERE
条件将要求public
等于自身,因此始终为true。否则使用:public
的值。