我问如何使CASE起作用,或为什么它不起作用(特别是考虑到相同的CASE表达式在纯SQL中起作用)。我不是在寻找替代解决方案。
我正在使用Doctrine ORM(及其SQL衍生查询语言-DQL),并尝试在WHERE子句中创建带有CASE表达式的DQL查询,但是Doctrine向我抛出错误。
DQL:
SELECT p FROM Entity\Product p WHERE (CASE WHEN p.price < 20 THEN p.quantity >= 30 ELSE p.quantity > 5 END)
我收到以下错误:
[Syntax Error] line 0, col 87: Error: Expected Doctrine\ORM\Query\Lexer::T_ELSE, got '>'
(在上面的>= 30
附近)
我不知道自己在做什么错。我知道DQL支持CASE表达式。我已经找到了使用它们的答案。至少堆栈跟踪具有解析器调用以确认这一点。
相同的SQL语句:
SELECT p.* FROM product p WHERE (CASE WHEN p.price < 20 THEN p.quantity >= 30 ELSE p.quantity > 5 END)
可以正常工作。
答案 0 :(得分:3)
在DQL的formal grammar的帮助下,我的同事是试图使用不受支持的功能。
目前(自Doctrine v2.6起),DQL完全不支持将CASE表达式评估为条件表达式。它只能计算语法中定义的ScalarExpression
,而不能是ConditionalExpression
的实例。
ScalarExpression ::= SimpleArithmeticExpression | StringPrimary | DateTimePrimary | StateFieldPathExpression | BooleanPrimary | CaseExpression | InstanceOfExpression
CaseExpression ::= GeneralCaseExpression | SimpleCaseExpression | CoalesceExpression | NullifExpression
GeneralCaseExpression ::= "CASE" WhenClause {WhenClause}* "ELSE" ScalarExpression "END"
WhenClause ::= "WHEN" ConditionalExpression "THEN" ScalarExpression
SimpleCaseExpression ::= "CASE" CaseOperand SimpleWhenClause {SimpleWhenClause}* "ELSE" ScalarExpression "END"
CaseOperand ::= StateFieldPathExpression | TypeDiscriminator
SimpleWhenClause ::= "WHEN" ScalarExpression "THEN" ScalarExpression
CoalesceExpression ::= "COALESCE" "(" ScalarExpression {"," ScalarExpression}* ")"
NullifExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")"