【发布时间】:2013-01-24 15:39:28
【问题描述】:
如果我一次返回自定义函数,它会起作用,但我想将它分成两个不同的用户定义函数。
按照这里的例子:
这是我的嵌套函数查询示例
SELECT *
FROM database
WHERE
FUNC_1(FUNC_2('field_name'),'constraint_default') =
FUNC_1(FUNC_2('value_entered'),'constraint_entered')
示例函数
<?php
namespace Foo\Bundle\FooBundle\DQL\NumericFunction;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
class BarFunction extends FunctionNode
{
public $stringExpression = null;
public $trimValueExpression = null;
public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->stringExpression = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_COMMA);
$this->trimValueExpression = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
return 'FUNC_1(' .
$this->stringExpression->dispatch($sqlWalker) . ',' .
$this->trimValueExpression->dispatch($sqlWalker) .
')';
}
}
现在 FUNC_2 非常接近 FUNC_1 但永远不会被调用,因为我认为 FUNC_1 返回已解析的语法,它删除了 FUNC_2 所需的语法。
<?php
namespace Foo\Bundle\FooBundle\DQL\NumericFunction;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
class FooFunction extends FunctionNode
{
public $stringExpression = null;
public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->stringExpression = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
return 'FUNC_2(' .
$this->stringExpression->dispatch($sqlWalker) .
')';
}
}
现在我创建了一个有效的组合函数:
<?php
namespace Foo\Bundle\FooBundle\DQL\NumericFunction;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
class CombinedFunction extends FunctionNode
{
public $stringExpression = null;
public $trimValueExpression = null;
public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->stringExpression = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_COMMA);
$this->trimValueExpression = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
return 'FUNC_1(FUNC_2(' .
$this->stringExpression->dispatch($sqlWalker) . '),' .
$this->trimValueExpression->dispatch($sqlWalker) .
')';
}
}
但我想知道是否可以使用嵌套的两个单独函数而不是创建这个组合函数?
想法?
更新:
添加 yml 配置
doctrine:
dbal:
...
orm:
entity_managers:
foo_manager:
dql:
numeric_functions:
FUNC_1: Foo\Bundle\FooBundle\DQL\NumericFunction\BarFunction
FUNC_2: Foo\Bundle\FooBundle\DQL\NumericFunction\FooFunction
COMB_FUNC: Foo\Bundle\FooBundle\DQL\NumericFunction\CombinedFunction
更新 #2
所以 FUNC_1 会匹配这个
FUNC_1(value_of_func_2,'constraint_default')
FUNC_2 会匹配这个
FUNC_2('field_name')
【问题讨论】:
-
解析器不处理这个问题吗? AFAIK,ArithmeticPrimary 可以是函数表达式。您在 DQL 中将其称为
DQL_F1(DQL_F2(...), ...)吗? -
@meze 是的,当我尝试单个函数时,我将其称为 FUNC_1(FUNC_2,因为这就是我在 yml 配置中为其命名的方式,添加了配置
-
嗯,它对我有用:
AND FUNC_1(FUNC_2('field_name','TEST'),'constraint_default') = FUNC_1(FUNC_2('field_name','TEST'),'constraint_default')已生成。你能分享一下FooFunction吗? -
FooFunction 只会匹配 FUNC_2 'FUNC_2('field_name','TEST')' 几乎一样,但我不需要检查 '),因为这是由 FUNC_1 检查的跨度>
-
其实你需要检查
)。 FUNC_1 只能看到 FUNC_1(expr1, expr2),也就是说它只能看到一个逗号。
标签: php symfony doctrine user-defined-functions dql