Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用PHP规则ORM的复杂WHERE子句_Php_Mysql_Doctrine_Dql - Fatal编程技术网

使用PHP规则ORM的复杂WHERE子句

使用PHP规则ORM的复杂WHERE子句,php,mysql,doctrine,dql,Php,Mysql,Doctrine,Dql,我正在使用PHP原则ORM构建我的查询。然而,我似乎不太明白如何使用DQL(条令查询语言)编写以下WHERE子句: 如何指定括号的位置 目前我的PHP代码中包含以下内容: ->where('name = ?', 'ABC') ->andWhere('category1 = ?', 'X') ->orWhere('category2 = ?', 'X') ->orWhere('category3 = ?', 'X') ->andWhere('price > ?'

我正在使用PHP原则ORM构建我的查询。然而,我似乎不太明白如何使用DQL(条令查询语言)编写以下WHERE子句:

如何指定括号的位置

目前我的PHP代码中包含以下内容:

->where('name = ?', 'ABC')
->andWhere('category1 = ?', 'X')
->orWhere('category2 = ?', 'X')
->orWhere('category3 = ?', 'X')
->andWhere('price > ?', 10)
但这会产生类似于

WHERE name='ABC' AND category1 = 'X' OR category2 = 'X' OR category3 = 'X' 
AND price > 10
由于操作顺序,它不会返回预期结果

另外,“where”、“andWhere”和“addWhere”方法之间是否有区别

更新 好的,似乎无法使用DQL进行复杂的查询,所以我一直在尝试手动编写SQL,并使用andWhere()方法添加它。然而,我使用WHERE..IN和document似乎去掉了我的括号:

$q->andWhere("(category1 IN $subcategory_in_clause
            OR category2 IN $subcategory_in_clause 
            OR category3 IN $subcategory_in_clause)");

至于where、andwhere和addwhere之间的区别,我认为与上次阅读源代码时没有明显区别。然而,我鼓励你阅读教义来源。它非常简单,有助于填补文档中的漏洞(有很多)。至于复杂的where语句,我自己也很想知道,但还没有必要使用它。

由于似乎无法使用DQL进行复杂的查询,我编写了以下SQL以传递给andWhere()方法:


请注意“AND TRUE”,这是一种黑客攻击,这样解析器就不会忽略外括号。

根据我的经验,每个复杂的
,其中
函数都分组在括号内(我使用的是原则1.2.1)

$q->where('name=?','ABC')
->其中('category1=?或category2=?或category3=?',数组('X','X','X'))
->andWhere('价格<?',10)
生成以下SQL:

WHERE name = 'ABC' 
  AND (category1 = 'X' OR category2 = 'X' OR category3 = 'X')
  AND price < 10
其中name='ABC'
和(类别1='X'或类别2='X'或类别3='X')
价格<10

其中可以概括为:
先前添加的条件感知WHERE语句

您可以安全地使用和where代替where。(它引入了非常小的开销,这在下面的第2个列表项中进行了说明。)

andWhere is的实施:(原则1.2.3)

可以理解为

  • 工艺参数
  • 如果在查询的where部分之前添加了另一个where语句,则将AND语句追加到where部分
  • 附加条件

  • 根据我的经验,我有时会看到以下两者之间的区别:

    $q->andWhere("(category1 IN $subcategory_in_clause
                OR category2 IN $subcategory_in_clause 
                OR category3 IN $subcategory_in_clause)");
    


    第一条语句写在3行上,第二条语句只写在一行上。我不相信,但这是不同的

    正确的方法可以在@Jekis中找到。下面是如何使用表达式生成器来解决这个问题,如@anushr的示例中所示

    $qb->where($qb->expr()->eq('name', ':name'))
      ->andWhere(
        $qb->expr()->orX(
          $qb->expr()->eq('category1', ':category1'),
          $qb->expr()->eq('category2', ':category2'),
          $qb->expr()->eq('category3', ':category3')
      )
      ->andWhere($qb->expr()->lt('price', ':price')
      ->setParameter('name', 'ABC')
      ->setParameter('category1', 'X')
      ->setParameter('category2', 'X')
      ->setParameter('category3', 'X')
      ->setParameter('price', 10);
    

    请您尝试一下这个变体,不确定它是否有效,但值得一试

    我认为anushr的解决方案要好得多。没有黑客攻击和使用准备好的声明。另一个解决方案可以在这里找到正是我所寻找的!这正是我讨厌教义的原因。这是不可能阅读和理解的。你也可以这样做:$ors=$qb->expr()->orX()$ors->add($qb->expr()->like('firstName',$qb->expr()->literal(%john%”))$ors->add($qb->expr()->like('lastName',$qb->expr()->literal(“%john%”))$qb->andWhere($ors);或者,您可以跳过所有这些噪声,将一个DQL字符串连接在一起。。。请确保您没有向SQL注入敞开大门。
    WHERE name = 'ABC' 
      AND (category1 = 'X' OR category2 = 'X' OR category3 = 'X')
      AND price < 10
    
    public function andWhere($where, $params = array())
    {
        if (is_array($params)) {
            $this->_params['where'] = array_merge($this->_params['where'], $params);
        } else {
            $this->_params['where'][] = $params;
        }
    
        if ($this->_hasDqlQueryPart('where')) {
            $this->_addDqlQueryPart('where', 'AND', true);
        }
    
        return $this->_addDqlQueryPart('where', $where, true);
    }
    
    $q->andWhere("(category1 IN $subcategory_in_clause
                OR category2 IN $subcategory_in_clause 
                OR category3 IN $subcategory_in_clause)");
    
    $q->andWhere("(category1 IN $subcategory_in_clause OR category2 IN $subcategory_in_clause OR category3 IN $subcategory_in_clause)");
    
    $qb->where($qb->expr()->eq('name', ':name'))
      ->andWhere(
        $qb->expr()->orX(
          $qb->expr()->eq('category1', ':category1'),
          $qb->expr()->eq('category2', ':category2'),
          $qb->expr()->eq('category3', ':category3')
      )
      ->andWhere($qb->expr()->lt('price', ':price')
      ->setParameter('name', 'ABC')
      ->setParameter('category1', 'X')
      ->setParameter('category2', 'X')
      ->setParameter('category3', 'X')
      ->setParameter('price', 10);
    
    $q->andWhere("category1 IN ( $subcategory_in_clause )
                  OR category2 IN ( $subcategory_in_clause )
                  OR category3 IN ( $subcategory_in_clause )");