Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 按顺序在原则2内使用DQL函数_Php_Mysql_Symfony_Doctrine Orm_Sql Order By - Fatal编程技术网

Php 按顺序在原则2内使用DQL函数

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排序。当我需要将数字字段排序为数字而不是字符

我正在使用MySQL数据库在Symfony 2.3和Doctrine 2.4中进行一个项目

我有一个FieldValue实体(简化):

我的问题是,
$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);
    }