2013-02-13 1 views
4

Я хочу сделать запрос DQL как:doctrine2 DQL подзапрос предел 1 строка

$dql = "select p 
     from AcmeDemoBundle:UserTypeA p 
     where p.UserTypeB = :id 
     and (
       select top 1 r.boolean 
       from AcmeDemoBundle:Registry r 
      ) 
     = true"; 

Но, кажется, что TOP 1 это не действует функция doctrine2.

Не могу понять, как ограничить результат подзапроса одной строкой.

+0

Аналогичный вопрос http://stackoverflow.com/questions/14234233/doctrine-2-limit-in-subquery , но нет ответа на это :( –

+0

Здесь http://stackoverflow.com/questions/24068947/ subquery-with-limit-in-doctrine может быть решением –

ответ

2

DQL не поддерживает ограничения на подзапросы и ни LIMIT, ни OFFSET.

См http://www.doctrine-project.org/jira/browse/DDC-885

+1

Я знаю, я знаю, я ищу любой альтернативный код. Не знаю, возможно ли с createQuery. –

+0

Сделайте это через NativeSQL (http: // docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/native-sql.html) – Ocramius

1

Хотя доктрина изначально не поддерживает это, вы могли бы реализовать пользовательскую функцию с именем FIRST() для достижения этой цели:

<?php 

use Doctrine\ORM\Query\AST\Functions\FunctionNode; 
use Doctrine\ORM\Query\AST\Subselect; 
use Doctrine\ORM\Query\Lexer; 
use Doctrine\ORM\Query\Parser; 
use Doctrine\ORM\Query\SqlWalker; 

/** 
* FirstFunction ::= 
*  "FIRST" "(" Subselect ")" 
*/ 
class FirstFunction extends FunctionNode 
{ 
    /** 
    * @var Subselect 
    */ 
    private $subselect; 

    /** 
    * {@inheritdoc} 
    */ 
    public function parse(Parser $parser) 
    { 
     $parser->match(Lexer::T_IDENTIFIER); 
     $parser->match(Lexer::T_OPEN_PARENTHESIS); 
     $this->subselect = $parser->Subselect(); 
     $parser->match(Lexer::T_CLOSE_PARENTHESIS); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function getSql(SqlWalker $sqlWalker) 
    { 
     return '(' . $this->subselect->dispatch($sqlWalker) . ' LIMIT 1)'; 
    } 
} 

(Подробнее: https://www.colinodell.com/blog/201703/limiting-subqueries-doctrine-2-dql)

Вы должны действительно использовать это только для чтения, поскольку Doctrine не будет включать в себя другие связанные объекты в результате (которые могут стать потерянными или потерянными, если вы сохраните их).

+0

Это единственное, что действительно работает. –