我想在Zend_Db中生成这个复杂的WHERE子句:
SELECT *
FROM 'products'
WHERE
status = 'active'
AND
(
attribute = 'one'
OR
attribute = 'two'
OR
[...]
)
;
我试过这个:
$select->from('product');
$select->where('status = ?', $status);
$select->where('attribute = ?', $a1);
$select->orWhere('attribute = ?', $a2);
那产生了:
SELECT `product`.*
FROM `product`
WHERE
(status = 'active')
AND
(attribute = 'one')
OR
(attribute = 'two')
;
我确实找到了一种方法来完成这项工作,但我觉得这有点“欺骗”,首先使用PHP组合“OR”子句,然后使用Zend_Db where()子句将它们组合起来。 PHP代码:
$WHERE = array();
foreach($attributes as $a):
#WHERE[] = "attribute = '" . $a . "'";
endforeach;
$WHERE = implode(' OR ', $WHERE);
$select->from('product');
$select->where('status = ?', $status);
$select->where($WHERE);
这产生了我想要的东西。但我很好奇是否有一种“官方”的方式来获取复杂的WHERE语句(实际上并不太复杂,只是添加一些括号)和Zend_Db工具,而不是先用PHP组合。
干杯!
答案 0 :(得分:22)
这将是获得指定括号的“官方”方式(参见Zend_Db_Select
文档中的示例#20):
$a1 = 'one';
$a2 = 'two';
$select->from('product');
$select->where('status = ?', $status);
$select->where("attribute = $a1 OR attribute = $a2");
所以,你所做的事情似乎是合理的,因为你不知道你提前有多少属性。
答案 1 :(得分:3)
如果使用所选答案,则需要记住在构造查询之前引用值以防止SQL注入。
使用Zend Db Select创建查询并引用值的另一个选项是分两个阶段完成:
/// we just use this select to create the "or wheres"
$select1->from('product');
foreach($attributes as $key => $a) {
if ($key == 0) {
/// we don't want "OR" for first one
$select1->where("attribute = ?", $a);
} else {
$select1->orWhere("attribute = ?", $a);
}
}
/// now we construct main query
$select2->from('product');
$select2->where('status = ?', $status);
$select2->where(implode(' ', $select1->getPart('where')));
这样Zend Db Select可以完成所有的SQL生成。一个老问题,但希望这个想法可能对有类似问题的人有用。
答案 2 :(得分:0)
我使用这个解决方案,似乎按照需要工作。
$select->from('product');
$select->where('status = ?', $status);
$select->where('(attribute = ?', $a1);
$select->orWhere('attribute = ?)', $a2);
答案 3 :(得分:0)
如果您的属性是同一个表列,并且您希望将其检查为等于多个值中的一个,那么您可以使用IN:
$select->from('product');
$select->where('status = ?', $status);
$select->where('attribute IN (?)', [$a1, $a2, ...]);
或
$select->where('attribute IN (:someName)');
$select->setParameter('someName', [$a1, $a2, ...]);
否则,除"attribute = $a1 OR attribute = $a2"