使用“SQL_CALC_FOUND_ROWS”和Doctrine NativeQuery获取总行数

时间:2013-12-17 11:04:08

标签: symfony doctrine-orm

我有一个简单的查询,它选择实体并使用限制语句。我正在使用Doctrine NativeQuery,因为我在sql查询中有FIELD()函数,因此我需要一组对象。 该查询有效。

但是我还需要记录总数,因此我在第一个查询中使用SQL_CALC_FOUND_ROWS。在第一次得到结果后,我创建了另一个ResultSetMapping,另一个$ nativeQuery,执行SELECT FOUND_ROWS() AS found_rows,并且我不断得到'1'的总数。

$rsm = new ResultSetMapping();

$rsm->addEntityResult('\\MyCompany\\Administration\\Domain\\Model\\Applicant\\Applicant', 'a');

$rsm->addFieldResult('a', 'first_name', 'firstName');
$rsm->addFieldResult('a', 'last_name', 'lastName');

$query = $this->em->createNativeQuery('SELECT SQL_CALC_FOUND_ROWS * FROM recruitment_applicant ORDER BY FIELD(id,5,15,8,17,2,1,16,9,7,11,6,10,12,13,14,18)', $rsm);

$result = $query->getResult(); // this result is ok



$sqlCountRows = "SELECT FOUND_ROWS() AS found_rows";

$countRowsRsm = new ResultSetMapping();

$countRowsRsm->addScalarResult('found_rows', 'foundRows');

$countRowsQuery = $this->em->createNativeQuery($sqlCountRows,$countRowsRsm);

$rowsCount = $countRowsQuery->getResult();

$total = $rowsCount[0]['foundRows']; // result is '1' when it should be '16'

我使用this示例。

2 个答案:

答案 0 :(得分:2)

  1. 您不必使用本机查询。 FIELD()非常容易实现为自定义DQL函数:

    1. 在Doctrine / Symfony文档中阅读DQL User Defined FunctionsHow to Register Custom DQL Functions
    2. FIELD()实施:

      use Doctrine\ORM\Query\AST\Functions\FunctionNode;
      use Doctrine\ORM\Query\Lexer;
      use Doctrine\ORM\Query\Parser; 
      use Doctrine\ORM\Query\SqlWalker;
      
      class Field extends FunctionNode
      {
          private $field = null;
          private $values = array();
      
          public function parse(Parser $parser)
          {
              $parser->match(Lexer::T_IDENTIFIER);
              $parser->match(Lexer::T_OPEN_PARENTHESIS);
      
              $this->field = $parser->arithmeticPrimary();
      
              while (count($this->values) < 1 || $parser->getLexer()->lookahead['type'] !== Lexer::T_CLOSE_PARENTHESIS) {
                  $parser->match(Lexer::T_COMMA);
                  $this->values[] = $parser->arithmeticPrimary();
              }
      
              $parser->match(Lexer::T_CLOSE_PARENTHESIS); 
          }
      
          public function getSql(SqlWalker $sqlWalker)
          {
              $values = array();
              foreach ($this->values as $value) {
                  $values[] = $value->dispatch($sqlWalker);
              }
      
              return sprintf('FIELD(%s, %s)', $this->field->dispatch($sqlWalker), implode(', ', $values));
          }
      } 
      
  2. 您不需要事件计数查询。但是,如果您需要COUNT(*)查询,则可以轻松克隆原始查询,并使用CountWalker从选择查询创建计数查询。

答案 1 :(得分:0)

我发现可能是问题的原因:Symfony2 profiler,queries部分,显示总共执行了22个查询。我的第一个查询连续运行第三个查询,第二个查询,返回行数的第13个查询执行。 如果在第一次查询后立即运行SQL_CALC_FOUND_ROWS,则SELECT FOUND_ROWS()有效。