Mit DQL-Funktionen innerhalb von Doctrine 2, UM DURCH

Ich mache ein Projekt in Symfony 2.3 mit der Lehre 2.4 MySQL-Datenbank.

Ich habe eine Entität von FieldValue (vereinfacht):

class FieldValue
{
    /**
     * The ID
     *
     * @var integer
     */
    protected $fieldValueId;

    /**
     * Id of associated Field entity
     *
     * @var integer
     */
    protected $fieldId;

    /**
     * Id of associated user
     *
     * @var integer
     */
    protected $userId;

    /**
     * The value for the Field that user provided
     *
     * @var string
     */
    protected $userValue;

    /**
     * @var \MyProjectBundle\Entity\Field
     */
    protected $field;

    /**
     * @var \MyProjectBundle\Entity\User
     */
    protected $user;

Das problem, das ich habe, ist die Tatsache, dass $userValue, während es LONGTEXT in meiner Datenbank darstellen können, entweder eigentlichen text, Wert , Datum oder Zahl, abhängig von der Art der Field.

Bereich können dynamisch Hinzugefügt werden. Nach hinzufügen eines jeden der Benutzer alle anderen Benutzer können auch füllen Sie den eigenen Wert für das Feld.

Beim Abfragen der Datenbank, die ich verwenden orderBy zum Sortieren nach einer bestimmten Spalte kann auch eines der Felder. In diesem Fall muss ich Sortieren $userValue. Dies ist problematisch, wenn ich mehrere Felder sortiert als zahlen und nicht als strings ('123' ist kleiner als '9' in diesem Fall...).

Die Lösung (dachte ich) ist CAST die $sort, so würde ich in die SQL folgendermaßen:

ORDER BY CAST(age AS SIGNED INTEGER) ASC

Da die Lehre nicht über einen eingebauten DQL-Funktion für diesen, ich nahm mir die Freiheit hinzuzufügen, dass mein Projekt als INT DQL-Funktion (Dank Jasper N. Brouwer):

class CastAsInteger extends FunctionNode
{
    public $stringPrimary;

    public function getSql(SqlWalker $sqlWalker)
    {
        return 'CAST(' . $this->stringPrimary->dispatch($sqlWalker) . ' AS SIGNED INTEGER)';
    }

    public function parse(Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);

        $this->stringPrimary = $parser->StringPrimary();

        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
    }
}

So glücklich mit mir selbst zu finden, eine einfache Lösung habe ich gemacht:

$sort = "INT(".$sort.")";

$queryBuilder->orderBy($sort, $dir);

hervorgebracht erwartet DQL:

ORDER BY INT(age) ASC

Sondern produzierte auch eine Ausnahme:

Eine Ausnahme geworfen wurde, während das Rendern von einem template ("[Syntax Error] line 0, col 12272: Fehler: Expected end of string, got '('") in MyProject...

So, ich habe versucht, herauszufinden, was Los ist und habe in diesem in Doctrine\ORM\Query\Parser.php:

/**
     * OrderByItem ::= (
     *      SimpleArithmeticExpression | SingleValuedPathExpression |
     *      ScalarExpression | ResultVariable
     * ) ["ASC" | "DESC"]
     *
     * @return \Doctrine\ORM\Query\AST\OrderByItem
     */
    public function OrderByItem()
    {
        ...
    }

Bedeutet das, dass es keine Möglichkeit gibt, zu verwenden DQL-Funktionen in ORDER BY?
Und wenn dies der Fall ist - gibt es eine andere Möglichkeit, dies zu erreichen?

UPDATE

Ich eigentlich schon haben INT verwendet in meiner select-Abfrage, innerhalb CASE WHEN:

if ($field->getFieldType() == 'number') {
    $valueThen = "INT(".$valueThen.")";
}

$newFieldAlias = array("
    (CASE
        WHEN ...
        THEN ".$valueThen."
        ELSE ...
        END
    ) as ".$field->getFieldKey());

Später auf der $newFieldAlias wird zur Abfrage Hinzugefügt.

Ändert sich nichts...

UPDATE 2

Selbst wenn ich ein zusätzliches hinzufügen, wählen Sie die Abfrage, deren Ergebnis in diesem DQL:

SELECT age, INT(age) as int_age

und dann die Art, wie, die:

ORDER BY int_age ASC

Ich noch nicht het das richtige Ergebnis.

Habe ich überprüft var_dump aus $query->getResult(), und das ist, was ich habe:

'age' => string '57' (length=2)      
'int_age' => string '57' (length=2)

Wie CAST spielt keine Rolle. Ich bin ratlos...

  • Ich denke, die Art und Weise, die ich bekam, um dieses war es, alias-Feld ein, um dann durch den alias. So könnte man versuchen, 'INT(".$Art.") als SortBy' in der select-Feldern Teil und dann, um auf das alias.
  • Siehe mein update oben
  • Ja sorry alle meine Lehre Zeug ist bei der Arbeit, so kann ich nicht überprüfen, aber ich erinnere mich mit einem ähnlichen Problem.
Schreibe einen Kommentar