Php 按顺序在原则2内使用DQL函数
我正在使用MySQL数据库在Symfony 2.3和Doctrine 2.4中进行一个项目 我有一个FieldValue实体(简化): 我的问题是,Php 按顺序在原则2内使用DQL函数,php,mysql,symfony,doctrine-orm,sql-order-by,Php,Mysql,Symfony,Doctrine Orm,Sql Order By,我正在使用MySQL数据库在Symfony 2.3和Doctrine 2.4中进行一个项目 我有一个FieldValue实体(简化): 我的问题是,$userValue虽然在我的数据库中是长文本,但它可以表示实际文本值、日期或数字,具体取决于字段的类型 可以动态添加该字段。向任何用户添加一个后,其他用户也可以为该字段填充它自己的值 在查询数据库时,我使用orderBy对特定列进行排序,该列也可以是这些字段之一。在这种情况下,我需要按$userValue排序。当我需要将数字字段排序为数字而不是字符
$userValue
虽然在我的数据库中是长文本
,但它可以表示实际文本值、日期或数字,具体取决于字段的类型
可以动态添加该字段。向任何用户添加一个后,其他用户也可以为该字段填充它自己的值
在查询数据库时,我使用orderBy对特定列进行排序,该列也可以是这些字段之一。在这种情况下,我需要按$userValue
排序。当我需要将数字字段排序为数字而不是字符串时,这是有问题的('123'在这种情况下小于'9')
它的解决方案(我认为)是CAST
对$sort
进行排序,因此我将得到如下SQL:
ORDER BY CAST(age AS SIGNED INTEGER) ASC
由于Doctrine没有内置的DQL函数,我冒昧地将其作为INT
DQL函数添加到我的项目中(感谢):
很高兴自己找到了一个简单的解决方案,我做到了:
$sort = "INT(".$sort.")";
$queryBuilder->orderBy($sort, $dir);
产生了预期的DQL:
ORDER BY INT(age) ASC
但也产生了一个例外:
在呈现模板的过程中引发了异常(“[Syntax Error]第0行,第12272列:错误:预期字符串结尾,在MyProject中得到“(”)。
因此,我试图找出发生了什么,并在Doctrine\ORM\Query\Parser.php
中对此进行了探讨:
/**
* OrderByItem ::= (
* SimpleArithmeticExpression | SingleValuedPathExpression |
* ScalarExpression | ResultVariable
* ) ["ASC" | "DESC"]
*
* @return \Doctrine\ORM\Query\AST\OrderByItem
*/
public function OrderByItem()
{
...
}
这是否意味着不可能在
ORDER BY中使用DQL函数?
如果是这样的话,有没有其他方法来实现这一点
更新
实际上,我已经在select查询中使用了INT,在CASE WHEN
中:
if ($field->getFieldType() == 'number') {
$valueThen = "INT(".$valueThen.")";
}
$newFieldAlias = array("
(CASE
WHEN ...
THEN ".$valueThen."
ELSE ...
END
) as ".$field->getFieldKey());
稍后,$newFieldAlias
将添加到查询中
不会改变任何事情
更新2
即使我向查询中添加了额外的select,也会产生以下DQL:
SELECT age, INT(age) as int_age
然后像这样排序:
ORDER BY int_age ASC
我仍然没有得到正确的结果
我已经从$query->getResult()
中检查了var\u dump
,这是我得到的:
'age' => string '57' (length=2)
'int_age' => string '57' (length=2)
Like CAST不重要。我不知道…原则DQL不接受函数作为排序标准,但它接受“结果变量”。这意味着您可以执行以下操作:
$q = $this->createQueryBuilder('e')
->addSelect('INT(age) as HIDDEN int_age')
->orderBy('int_age');
默认情况下,条令2不支持INT,但您可以使用age+0
$q = $this->createQueryBuilder('e')
->addSelect('age+0 as HIDDEN int_age')
->orderBy('int_age');
只要用这个:
->orderBy('u.age + 0', 'ASC');
这是parser.php文件中的问题。我有类似的问题,我解决了这个问题以替换我的parser文件中的以下代码
/**
* OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}*
*
* @return \Doctrine\ORM\Query\AST\OrderByClause
*/
public function OrderByClause()
{
$this->match(Lexer::T_ORDER);
$this->match(Lexer::T_BY);
$orderByItems = array();
$orderByItems[] = $this->OrderByItem();
while ($this->lexer->isNextToken(Lexer::T_COMMA)) {
$this->match(Lexer::T_COMMA);
$orderByItems[] = $this->OrderByItem();
}
return new AST\OrderByClause($orderByItems);
}
我想我解决这个问题的方法是给字段加上别名,然后按别名排序。所以你可以试试“INT”(“.$sort”)如“选择字段”部分中的“排序”,然后在该别名上排序。是的,很抱歉,我所有的条令资料都在工作中,因此我无法检查它,但我确实记得有一个类似的问题。感谢您的回答,请检查更新2您仍然以字符串而不是整数形式获得结果的事实与原始问题无关。请参阅
->orderBy('u.age + 0', 'ASC');
/**
* OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}*
*
* @return \Doctrine\ORM\Query\AST\OrderByClause
*/
public function OrderByClause()
{
$this->match(Lexer::T_ORDER);
$this->match(Lexer::T_BY);
$orderByItems = array();
$orderByItems[] = $this->OrderByItem();
while ($this->lexer->isNextToken(Lexer::T_COMMA)) {
$this->match(Lexer::T_COMMA);
$orderByItems[] = $this->OrderByItem();
}
return new AST\OrderByClause($orderByItems);
}