我在Symfony上编写了一个简单的自定义学说函数,它根据实体的bithdate计算AGE。这是我的功能:
class AgeFunction extends FunctionNode
{
private $birthDate;
public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->birthDate = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
$bday = $this->birthDate->dispatch($sqlWalker);
$currDate = DateFormatter::formatDate(new \DateTime());
return "TIMESTAMPDIFF(YEAR, {$bday}, '{$currDate}')";
}
}
以下是我如何使用它:
public function getAge()
{
$qb = $this->createQueryBuilder('s')
->select('AGE(s.dateOfBirth)')
->orderBy('s.id', 'DESC');
dump($qb->getQuery()->getResult());
}
这是生成的查询:
SELECT TIMESTAMPDIFF(YEAR,s0_.date_of_birth,' 2017-04-13')AS sclr_0 FROM suspect s0_ ORDER BY s0_.id DESC;
我认为这里的错误是s0_.date_of_birth永远不会得到实际值,因为当我手动更换它时效果很好。
那我该怎么做呢?感谢。
答案 0 :(得分:1)
也许你最初还是想做别的事,但是对我而言,业务要求似乎很奇怪,因为你只是想要获得最后一个人的年龄。无论如何,让我暂时忽略它,专注于你需要的东西。我检查了下面的例子并且工作正常。
<强> DQL 强>
namespace My\Bundle\Product\APIBundle\Entity\DQL;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;
class TimestampDiff extends FunctionNode
{
public $value;
public function parse(Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->value = $parser->StringPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(SqlWalker $sqlWalker)
{
return sprintf(
'TIMESTAMPDIFF(YEAR, %s, %s)',
$this->value->dispatch($sqlWalker),
date('Y-m-d')
);
}
}
<强> REPOSITORY 强>
public function findAge()
{
$qb = $this->createQueryBuilder('s')
->select('TIMESTAMPDIFF(s.dateOfBirth) AS Age')
->orderBy('s.id', 'DESC')
->setMaxResults(1);
return $qb->getQuery()->getResult(Query::HYDRATE_SIMPLEOBJECT);
}
拨打强>
$p = $this->suspectRepository->findAge();
注册 (我的设置不同,因此您可以查看下面的链接以使其适用于您的设置)
# app/config.yml
doctrine:
dbal:
default_connection: hello
connections:
hello:
driver: "%database_driver%"
host: "%database_host%"
....
....
orm:
default_entity_manager: hello
entity_managers:
hello:
dql:
string_functions:
TIMESTAMPDIFF: My\Bundle\Product\APIBundle\Entity\DQL\TimestampDiff
connection: hello
....
<强> RESULT 强>
SELECT
TIMESTAMPDIFF(YEAR, s0_.date_of_birth, 2017-04-13) AS sclr_0
FROM suspect s0_
ORDER BY s0_.id DESC
LIMIT 1