【问题标题】:Complex WHERE clause with Zend_Db using multiple AND OR operatorsZend_Db 的复杂 WHERE 子句使用多个 AND OR 运算符
【发布时间】:2010-12-07 23:05:25
【问题描述】:

我想在 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 工具而不是先在 PHP 中组合它来获取复杂的 WHERE 语句(实际上并不太复杂,只是添加一些括号)的“官方”方法。

干杯!

【问题讨论】:

    标签: php sql zend-framework zend-db


    【解决方案1】:

    这将是获取指定括号的“官方”方式(参见 Zend_Db_Select 文档中的示例 #20):

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

    因此,鉴于您事先不知道自己有多少属性,因此您所做的似乎是合理的。

    【讨论】:

    • 是的,您的解决方案来自 ZF 参考指南,基本上就是我提出最后一个示例的方式。也许那是这样做的正确方法。假设 Zend_Db_Select (ZDS) 会为您生成 SQL,但我们不得不在 ZDS 之外生成它的一部分,这只是感觉违反直觉。也许,这是可以使用扩展的东西,所以我们可以将所有代码保留在 Zend_Db_Select 中。
    • Zend_Db_Select 链接对我不起作用这是文档的更新链接。
    【解决方案2】:

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

    【讨论】:

    • 所有答案中最好最干净的,对我帮助很大。 Zend 也应该得到更好的支持
    【解决方案3】:

    我使用这个解决方案,它似乎可以正常工作。

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

    【讨论】:

      【解决方案4】:

      如果你的属性是同一个表列并且你想检查它是否等于几个值之一,那么你可以使用 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" 做出上述决定

      【讨论】:

        猜你喜欢
        • 2020-03-06
        • 1970-01-01
        • 1970-01-01
        • 2021-02-02
        • 1970-01-01
        • 2014-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多