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.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Lehre DQL nicht akzeptieren Funktionen als Sortierkriterium aber es akzeptieren, einen "Ergebnis-Variablen". Es bedeutet, dass Sie Folgendes tun können:
Lehre 2 nicht unterstützt INT standardmäßig, aber Sie können Alter+0.
Ist es ein problem in deinem parser.php Datei. Ich habe eine ähnliche Art von Problem, und ich das Problem lösen, ersetzen Sie folgenden code in meinem parser-Datei.
Nutzen Sie einfach dieses: