我为DQL编写了一个自定义函数:
<?php namespace Bundle\DQL\Functions;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\SqlWalker;
use Doctrine\ORM\Query\Parser;
/**
* "DATE_COMPARE" "(" ArithmeticPrimary "," ComparisonOperator "," ArithmeticPrimary ")"
*/
class DateCompareFunction extends FunctionNode
{
public $date1;
public $date2;
public $operator;
/**
* @override
* @param SqlWalker $sqlWalker
* @return string
* @throws \Doctrine\DBAL\DBALException
*/
public function getSql(SqlWalker $sqlWalker)
{
return sprintf(
'TRUNC(%s) %s TRUNC(%s)',
$this->date1->dispatch($sqlWalker),
$this->operator,
$this->date2->dispatch($sqlWalker)
);
}
/**
* @override
* @param Parser $parser
*/
public function parse(Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->date1 = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_COMMA);
$this->operator = $parser->ComparisonOperator();
$parser->match(Lexer::T_COMMA);
$this->date2 = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
}
我的stmt看起来像这样:
$query = $em->createQueryBuilder()
->select('evt')
->from('Application\Model\Event', 'evt')
->where('evt.USR_ID in (:uid)')
->setParameter('uid', $usersId);
if (null !== $from) {
$query->andWhere('DATE_COMPARE(evt.DAY, >, TO_DATE(:from, \'yyyy-mm-dd\'))')
->setParameter('from', $from);
问题是Doctrine因没有比较符号的WHERE
语句而引发异常:
object(Doctrine\ORM\Query\QueryException)[347]
protected 'message' => string '[Syntax Error] line 0, col 130: Error: Expected =, <, <=, <>, >, >=, !=, got ')'' (length=80)
private 'string' (Exception) => string '' (length=0)
protected 'code' => int 0
protected 'file' => string 'C:\Workspace\app\hcalendar\vendor\doctrine\orm\lib\Doctrine\ORM\Query\QueryException.php' (length=88)
protected 'line' => int 52
private 'trace' (Exception) =>
我尝试添加stmt = TRUE
,但生成的语句不是oracle所理解的,我可以在没有任何比较符号的情况下执行where语句吗? (只是一个真/假函数返回)
答案 0 :(得分:0)
为什么需要此功能?你可以在没有自定义函数的情况下执行where条件,只需写:
$query->andWhere('evt.day > :from')->setParameter('from', $from);
其中变量$from
应该是一个DateTime对象,如果你想要Oracle TRUNC
函数,你可以自己实现它,就像在这里https://github.com/ZeinEddin/ZeDoctrineExtensions/blob/master/lib/ZeDoctrineExtensions/Query/Oracle/TruncDate.php一样,只需像这样使用它:
$query->andWhere('trunc(evt.day) > :from')->setParameter('from', $from);
如果您需要,可以为ZF2项目安装this module,并且您已准备好在项目中使用TruncDate
功能