Zend_Db 的复杂 WHERE 子句使用多个 AND OR 运算符

发布于 2024-10-06 09:25:18 字数 1073 浏览 1 评论 0 原文

我想在 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);

这产生了我正在寻找的东西。但我很好奇是否有一种“官方”方法可以使用 Zend_Db 工具获取复杂的 WHERE 语句(实际上并不太复杂,只是添加一些括号),而不是先将其组合到 PHP 中。

干杯!

I want to generate this complex WHERE clause in Zend_Db:

SELECT * 
FROM 'products' 
WHERE 
    status = 'active' 
    AND 
    (
        attribute = 'one' 
        OR 
        attribute = 'two' 
        OR 
        [...]
    )
;

I've tried this:

$select->from('product');
$select->where('status = ?', $status);
$select->where('attribute = ?', $a1);
$select->orWhere('attribute = ?', $a2);

and that produced:

SELECT `product`.* 
FROM `product` 
WHERE 
    (status = 'active') 
    AND 
    (attribute = 'one') 
    OR 
    (attribute = 'two')
;

I did figure out one method of making this work but I felt it was sort of 'cheating' by using PHP to combine the "OR" clauses first and then combine them using Zend_Db where() clause. PHP code:

$WHERE = array();
foreach($attributes as $a):
    #WHERE[] = "attribute = '" . $a . "'";
endforeach;
$WHERE = implode(' OR ', $WHERE);

$select->from('product');
$select->where('status = ?', $status);
$select->where($WHERE);

That produced what I was looking for. But I'm curious if there's an "official" way of getting that complex WHERE statement (which really isn't too complex, just adding some parenthesis) with using the Zend_Db tool, instead of combining it in PHP first.

Cheers!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

从﹋此江山别 2024-10-13 09:25:18

这将是获取指定括号的“官方”方式(请参阅 Zend_Db_Select 文档):

$a1 = 'one';
$a2 = 'two';
$select->from('product');
$select->where('status = ?', $status);
$select->where("attribute = $a1 OR attribute = $a2");

因此,鉴于您不知道提前有多少个属性,您所做的事情似乎确实合理。

This would be the 'official' way to get you the parentheses as specified (see Example #20 in the Zend_Db_Select documentation):

$a1 = 'one';
$a2 = 'two';
$select->from('product');
$select->where('status = ?', $status);
$select->where("attribute = $a1 OR attribute = $a2");

So, what you are doing does seem reasonable, given that you do not know how many attributes you have ahead of time.

等风来 2024-10-13 09:25:18

如果使用所选答案,您需要记住在构造查询之前引用这些值以防止 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。这是一个老问题,但希望这个想法对有类似问题的人有用。

If using the chosen answer you would need to remember to quote the values before constructing the query to guard against SQL injection.

Another option that uses Zend Db Select to create the query and also quotes the values would be to do it in 2 stages:

/// 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')));

This way Zend Db Select does all the SQL generatation. An old question but hopefully this idea might be of use to someone with a similar problem.

め七分饶幸 2024-10-13 09:25:18

我使用这个解决方案,它似乎按需要工作。

$select->from('product');
$select->where('status = ?', $status);
$select->where('(attribute = ?', $a1);
$select->orWhere('attribute = ?)', $a2);

I use this solution and it seems work as wanted.

$select->from('product');
$select->where('status = ?', $status);
$select->where('(attribute = ?', $a1);
$select->orWhere('attribute = ?)', $a2);
樱花落人离去 2024-10-13 09:25:18

如果您的属性是同一表列,并且您想要检查它是否等于多个值之一,那么您可以使用 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"

If your attribute is the same table column and you want to check it for equal to one of several values, than you can use IN :

$select->from('product');
$select->where('status = ?', $status);
$select->where('attribute IN (?)', [$a1, $a2, ...]);

or

$select->where('attribute IN (:someName)');
$select->setParameter('someName', [$a1, $a2, ...]);

Otherwise I see no alternative to decision above with "attribute = $a1 OR attribute = $a2"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文