web-dev-qa-db-ja.com

Doctrine Querybuilderで `DATE()`を使用する

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です。 :datestringDATE形式)のみです。

次のバリエーションは機能しませんでした。

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

Error: Expected known function, got 'DATE'

ここでの正しい使用法は何ですか?

9
Daniel W.

これは実際には非常に一般的な質問です。すべての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セクションに接続します:

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.htmlhttp://symfony.com/doc/current/ Cookbook/doctrine/custom_dql_functions.htmlhttp://symfony.com/doc/current/reference/configuration/doctrine.html

より多くのSQL関数を備えた他のバンドルがあります。奇妙なことに、私が数年前に初めて見たとき、それらのどれも日付が定義されていませんでした。だから私は自分で作った。

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

アップデート01

タグを注意深くチェックせず、これがSymfony2アプリケーションであると想定しました。 Dateクラスは同じままです。 doctrine構成オブジェクトを取得することで接続します。

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

詳細については、Doctrineリンクを確認してください。

9
Cerad

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'));
13
Daniel W.