我想执行参数化查询以通过用户提供的参数执行搜索。有很多参数,并不是所有参数都会一直供应。如何创建指定所有可能参数的标准查询,但如果用户没有选择有意义的参数值,则忽略其中一些参数?
这是一个虚构的例子来说明我的目标
$sql = 'SELECT * FROM people WHERE first_name = :first_name AND last_name = :last_name AND age = :age AND sex = :sex';
$query = $db->prepare($sql);
$query->execute(array(':first_name' => 'John', ':age' => '27');
显然,这不起作用,因为提供的参数数量与预期参数的数量不匹配。我是否必须每次只使用WHERE子句中包含的指定参数来制作查询,或者是否有办法让某些参数被忽略或在检查时始终返回true?
答案 0 :(得分:8)
SELECT * FROM people
WHERE (first_name = :first_name or :first_name is null)
AND (last_name = :last_name or :last_name is null)
AND (age = :age or :age is null)
AND (sex = :sex or :sex is null)
传递参数时,请为您不需要的参数提供null
。
请注意,为了能够以这种方式运行查询,必须转换emulation mode
for PDO {/ 1}}
答案 1 :(得分:2)
首先,首先将$sql
字符串更改为:
$sql = 'SELECT * FROM people WHERE 1 = 1';
WHERE 1 = 1
将允许您不包含任何其他参数...
接下来,选择性地将$sql
字符串连接到任何具有有意义值的附加参数:
$sql .= ' AND first_name = :first_name'
$sql .= ' AND age = :age'
您的$sql
字符串现在只包含您计划提供的参数,因此您可以像以前一样继续:
$query = $db->prepare($sql);
$query->execute(array(':first_name' => 'John', ':age' => '27');
答案 2 :(得分:1)
如果您无法通过更改查询来解决问题...有几个库可以帮助您组装查询。我过去曾使用Zend_Db_Select
,但每个框架可能都有类似的东西:
$select = new Zend_Db_Select;
$select->from('people');
if (!empty($lastName)) {
$select->where('lastname = ?', $lastname);
}
$select->order('lastname desc')->limit(10);
echo $select; // SELECT * FROM people WHERE lastname = '...' ORDER BY lastname desc LIMIT 10
答案 3 :(得分:0)
我已经测试了@juergen给出的解决方案,但由于绑定变量的数量不匹配,因此它会产生PDOException。无论参数如何,以下(不那么优雅)代码都可以工作:
function searchPeople( $inputArr )
{
$allowed = array(':first_name'=>'first_name', ':last_name'=>'last_name', ':age'=>'age', ':sex'=>'sex');
$sql = 'SELECT * FROM sf_guard_user WHERE 1 = 1';
foreach($allowed AS $key => $val)
{
if( array_key_exists( $key, $inputArr ) ){
$sql .= ' AND '. $val .' = '. $key;
}
}
$query = $db->prepare( $sql );
$query->execute( $inputArr );
return $query->fetchAll();
}
<强>用法:强>
$result = searchPeople(array(':first_name' => 'John', ':age' => '27'));