在Doctrine Querybuilder中使用`DATE()`

时间:2014-09-23 14:53:12

标签: date datetime doctrine-orm doctrine query-builder

我需要获取DATE(a.when)与字符串2014-09-30匹配的所有行。

$builder = $this->em->createQueryBuilder();
$builder->select('a')
        ->from('Entity\Appointment', 'a')
        ->andWhere('a.when = :date')
        ->setParameter('date', $date);

a.when是一个完整的DATETIME; :date只是stringDATE格式)。

以下和变体不起作用:

        ->andWhere('DATE(a.when) = :date')

Error: Expected known function, got 'DATE'

这里的正确用法是什么?

3 个答案:

答案 0 :(得分:12)

感谢andy,现在就使用它:

$builder = $this->em->createQueryBuilder();
$builder->select('a')
        ->from('Entity\Appointment', 'a')
        ->andWhere('a.when >= :date_start')
        ->andWhere('a.when <= :date_end')
        ->setParameter('date_start', $date->format('Y-m-d 00:00:00'))
        ->setParameter('date_end',   $date->format('Y-m-d 23:59:59'));

答案 1 :(得分:9)

这实际上是一个非常常见的问题。 事实证明,并非所有的sql数据库都支持DATE函数,因此负责Doctrine的优秀人员决定不再支持它。

他们希望他们这样做,因为这会为一群人节省相当多的努力。

所以将这个相当神奇的类添加到你的项目中:

namespace Cerad\Bundle\CoreBundle\Doctrine\DQL;

use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;

class Date extends FunctionNode
{
    public $date;

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
    {
        return "DATE(" . $sqlWalker->walkArithmeticPrimary($this->date) . ")";
    }
    public function parse(\Doctrine\ORM\Query\Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);

        $this->date = $parser->ArithmeticPrimary();

        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
    }
}

然后在app / config.yml的学说部分中将其连接起来:

doctrine:
  orm:
  default_entity_manager:       default
  auto_generate_proxy_classes: %kernel.debug%

  entity_managers:

    default:
      connection: default
      ...
      dql:
        datetime_functions:
          date:  Cerad\Bundle\CoreBundle\Doctrine\DQL\Date

http://doctrine-orm.readthedocs.org/en/latest/cookbook/dql-user-defined-functions.html http://symfony.com/doc/current/cookbook/doctrine/custom_dql_functions.html http://symfony.com/doc/current/reference/configuration/doctrine.html

还有其他捆绑包含更多sql函数。奇怪的是,几年前我第一次看,没有人定义日期。所以我就是自己制作的。

=============================================== =====================

更新01

我没有仔细检查标签,并认为这是一个Symfony 2应用程序。 Date类保持不变。您可以通过获取学说配置对象来连接它。

$config = new \Doctrine\ORM\Configuration();
$config->addCustomDatetimeFunction('DATE', 'blahblah\Date');

查看Doctrine链接了解详情。

答案 2 :(得分:0)

使用$ qb-> expr()-> between()在相同位置和位置使用另一种方法:


    $builder = $this->em->createQueryBuilder(); $builder->select('a')
                ->from('Entity\Appointment', 'a')
                ->andWhere($qb->expr()->between('a.when', ':date_start', ':date_end'))
                ->setParameter('date_start', $date->format('Y-m-d 00:00:00'))
                ->setParameter('date_end',   $date->format('Y-m-d 23:59:59'));