I am trying to get Doctrine2 Entities, ordered by their ID which apparently is a String even though it contains only Numbers. So what I would like to do is
You should be able to add your own function to implement this feature.
The class would look something like this:
namespace MyProject\Query;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;
class CastAsInteger extends FunctionNode
{
public $stringPrimary;
public function getSql(SqlWalker $sqlWalker)
{
return 'CAST(' . $this->stringPrimary->dispatch($sqlWalker) . ' AS 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);
}
}
You'll need to register your function:
$config = $em->getConfiguration();
$config->addCustomNumericFunction('INT', 'MyProject\Query\CastAsInteger');
Then you can use it:
SELECT e, INT(e.id) AS HIDDEN orderId FROM Namespace\Bla\MyEntity e ORDER BY orderId
PS: By adding the HIDDEN
keyword, the alias orderId
won't be in the results (and is only used for ordering).
Think it's better to use some extra functional in such cases ( without trying "to circumvent" theirs). E.g. an excellent solution adding almost all necessary ( not supported from box ) stuff for Doctrine 2
is DoctrineExtensions by beberlei (github). With it it's possible to use directly CAST
-statement like in OP's case:
("Symfony-example") E.g. in your config.xml
add lines:
orm:
..
entity_managers:
....
dql:
....
string_functions:
CAST: DoctrineExtensions\Query\Mysql\Cast
Then U can use it like:
SELECT entity1, CAST(entity1.id AS integer) AS orderId
FROM Namespace\Bla\MyEntity
ORDER BY orderId
Based on Jasper N. Brouwer answer, this is a little bit enhanced solution:
<?php
namespace MyProject\Query;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;
class Cast extends FunctionNode
{
/** @var \Doctrine\ORM\Query\AST\PathExpression */
protected $first;
/** @var string */
protected $second;
/**
* @param SqlWalker $sqlWalker
*
* @return string
*/
public function getSql(SqlWalker $sqlWalker)
{
return sprintf("CAST(%s AS %s)",
$this->first->dispatch($sqlWalker),
$this->second
);
}
/**
* @param Parser $parser
*
* @return void
*/
public function parse(Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->first = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_AS);
$parser->match(Lexer::T_IDENTIFIER);
$this->second = $parser->getLexer()->token['value'];
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
}
Now it should be possible to write DQL like this:
SELECT e, CAST(e.id AS integer) AS HIDDEN orderId FROM Namespace\Bla\MyEntity e ORDER BY orderId
I think you want order by entity1
. if your entity1 data type is integer then no need to change it into integer or if it is not then you should do it. below is query for you.try this one.
select entity1,cast(entity1 as integer) as order_id from Table_Name order by 1 asc;
Not sure if this works, but to access an entity ID you need the IDENTITY() DQL function. Try this:
SELECT entity1 FROM Namespace\Bla\MyEntity ORDER BY IDENTITY(entity1)
I just did something similar in my own code yesterday. I was able to do:
select cast(entity1 as int) as OrderID
from yourtablename
where yourconditions
I had to actually cast mine as money and then int, but if you don't have a decimal, you should not have that issue. You can also try casting as numeric or using convert instead of cast, but cast is better in this situation.
Why do you need entity1 as a column if you already have the same value in OrderID?