2011-09-13 9 views
14

Sto cercando di ottenere Doctrine2 Entities, ordinato dal loro ID che apparentemente è una stringa anche se contiene solo numeri. Quindi quello che vorrei fare è qualcosa di simile:Attributi CASTING per l'ordinazione su una query DQL Doctrine2

SELECT entity1, cast (entity1.id AS integer) AS orderId 
FROM Namespace\Bla\MyEntity 
ORDER BY orderId 

C'è un modo per fare qualcosa di simile in Doctrine2? Oppure, quale sarebbe la migliore pratica per ottenere il mio risultato se non riesco a cambiare il tipo di id (a causa delle esigenze del cliente, ovviamente)?


Attenzione: io non chiedo codice SQL, sto chiedendo una soluzione Doctrine2, preferibilmente in DQL

+0

penso che ti manca un '(' in linea 13. – DonJuwe

risposta

16

si dovrebbe essere in grado di add your own function a implementare questa funzione.

La classe sarebbe simile a questa:

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); 
    } 
} 

Avrai bisogno di registrare la vostra funzione:

$config = $em->getConfiguration(); 
$config->addCustomNumericFunction('INT', 'MyProject\Query\CastAsInteger'); 

Quindi è possibile utilizzarlo:

SELECT e, INT(e.id) AS HIDDEN orderId FROM Namespace\Bla\MyEntity e ORDER BY orderId 

PS: Aggiungendo la parola chiave HIDDEN, l'alias orderId non sarà nei risultati (ed è usato solo per ord rendo).

+0

Nella mia funzione, ho un 'SingleValuedPathExpression' come' u.group' e voglio "racchiudere" questo in un '" CAST ("SingleValuedPathExpression" AS DECIMAL (10,2)) "' usando gli oggetti Expression reali .. . Come potrei farlo? Che tipo di espressione sarebbe CAST ... essere quando si costruisce a mano? –

+0

ok non importa; Ho usato un'espressione personalizzata e ho modificato il suo metodo '-> dispatch()' per soddisfare le mie esigenze. Più pulito come previsto La dottrina è fantastica. :) –

+1

Se il database di destinazione è MySql, questa riga non funziona: 'return 'CAST ('. $ This-> stringPrimary-> dispatch ($ sqlWalker). 'AS integer)''; Prova questo: 'return 'CAST ('. $ This-> stringPrimary-> dispatch ($ sqlWalker). 'AS SIGNED)';' – Hokusai

0

Penso che volete l'ordine da entity1. se il tipo di dati entity1 è intero, non è necessario cambiarlo in numero intero o, in caso contrario, dovresti farlo. di seguito è la query per you.try questo.

select entity1,cast(entity1 as integer) as order_id from Table_Name order by 1 asc; 
+0

Come già detto non posso cambiarlo a causa dei requisiti del cliente –

+0

Poi hai la seconda opzione visualizzando e restituendo il valore .. –

3

provare questo da fuori, con la modifica del tipo di dati

select (entity1 * 1) as display_value, entity1 as return_value 
     from Table_Name 
    order by 1 asc; 
+0

sei consapevole che sto usando doctrine2 DQL e non MySQL? –

-2

Ho appena fatto qualcosa di simile nel mio codice ieri. Sono stato in grado di fare:

select cast(entity1 as int) as OrderID 
from yourtablename 
where yourconditions 

ho dovuto lanciare in realtà mio come soldi e poi int, ma se non si dispone di un numero decimale, non si dovrebbero avere quel problema. Puoi anche provare a lanciare come valori numerici o usare convert invece di cast, ma cast è meglio in questa situazione.

Perché avete bisogno di entity1 come colonna se avete già lo stesso valore in OrderID?

+1

sei consapevole che sto usando doctrine2 DQL e non MySQL? –

+1

Non ero a conoscenza di ciò e stavo usando sql per sqlserver, non mysql, bu sono molto simili – rainhider

0

Non sono sicuro che funzioni, ma per accedere a un ID entità è necessaria la funzione DQL IDENTITY(). Prova questo:

SELECT entity1 FROM Namespace\Bla\MyEntity ORDER BY IDENTITY(entity1) 
1

Basato su Jasper N.Brouwer risposta, questo è un po 'di soluzione migliorata bit:

<?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); 
    } 
} 

Ora dovrebbe dal possibile scrivere DQL come questo:

SELECT e, CAST(e.id AS integer) AS HIDDEN orderId FROM Namespace\Bla\MyEntity e ORDER BY orderId 
Problemi correlati