2013-03-13 14 views
27

mi piacerebbe costruire la seguente SQL utilizzando query builder di Doctrine:Dottrina generatore di query utilizzando inner join con condizioni

select c.* 
from customer c 
join phone p 
on p.customer_id = c.id 
and p.phone = :phone 
where c.username = :username 

Per prima cosa ho provato

$qb->select('c') 
    ->innerJoin('c.phones', 'p', Join::ON, $qb->expr()->andx(
     $qb->expr()->eq('p.customerId', 'c.id'), 
     $qb->expr()->eq('p.phone', ':phone') 
    )) 
    ->where('c.username = :username'); 

ma sto ottenendo il seguente errore

Error: expected end of string, got 'ON' 

Poi ho provato

$qb->select('c') 
    ->innerJoin('c.phones', 'p') 
    ->where('c.username = :username') 
    ->andWhere('p.phone = :phone'); 

che sembra funzionare. Tuttavia, qualcuno sa cosa c'è che non va nel primo tentativo? Mi piacerebbe fare il primo lavoro dal momento che assomiglia più strettamente a come è strutturato SQL. Grazie in anticipo!

Nota: so che possiamo anche scrivere mysql nativo o dql con Doctrine, ma preferirei il generatore di query.

EDIT: Di seguito è riportato l'intero codice

namespace Cyan\CustomerBundle\Repository; 

use Cyan\CustomerBundle\Entity\Customer; 
use Doctrine\ORM\EntityRepository; 
use Doctrine\ORM\Query\Expr\Join; 

class CustomerRepository extends EntityRepository 
{ 
    public function findCustomerByPhone($username, $phone) 
    { 
     $qb = $this->createQueryBuilder('c'); 

     $qb->select('c') 
      ->innerJoin('c.phones', 'p', Join::ON, $qb->expr()->andx(
       $qb->expr()->eq('p.customerId', 'c.id'), 
       $qb->expr()->eq('p.phone', ':phone') 
      )) 
      ->where('c.username = :username'); 

//  $qb->select('c') 
//   ->innerJoin('c.phones', 'p') 
//   ->where('c.username = :username') 
//   ->andWhere('p.phone = :phone'); 

     $qb->setParameters(array(
      'username' => $username, 
      'phone' => $phone->getPhone(), 
     )); 

     $query = $qb->getQuery(); 
     return $query->getResult(); 
    } 
} 
+0

Si può fornire l'intero messaggio di errore? – hacfi

+1

QueryException: [Errore di sintassi] riga 0, colonna 74: Errore: fine della stringa prevista, ottenuto "ON" –

risposta

61

Ho intenzione di rispondere alla mia stessa domanda.

  1. innerJoin dovrebbe usare la parola "CON" invece di "ON" (documentazione di Doctrine è imprecisa [13.2.6 metodi di supporto.]; [13.2.5 La classe Expr.] È corretto)
  2. bisogno per collegare le chiavi esterne nella condizione di join poiché sono già specificate nella mappatura delle entità.

Pertanto, i seguenti lavori per me

$qb->select('c') 
    ->innerJoin('c.phones', 'p', 'WITH', 'p.phone = :phone') 
    ->where('c.username = :username'); 

o

$qb->select('c') 
    ->innerJoin('c.phones', 'p', Join::WITH, $qb->expr()->eq('p.phone', ':phone')) 
    ->where('c.username = :username'); 
+1

Puoi completarlo con setParameters() per entrambi: telefono e: username? Ho un '' 'numero parametro non valido: il numero di variabili vincolate non corrisponde al numero di token ''' – lrkwz

+2

Quali condizioni metti in un WITH vs WHERE? –

8

È possibile esplicitamente avere un join come questo:

$qb->innerJoin('c.phones', 'p', Join::ON, 'c.id = p.customerId'); 

Ma è necessario utilizzare lo spazio dei nomi della classe Join dalla dottrina:

use Doctrine\ORM\Query\Expr\Join; 

Oppure se preferisci:

$qb->innerJoin('c.phones', 'p', Doctrine\ORM\Query\Expr\Join::ON, 'c.id = p.customerId'); 

In caso contrario, Join class non verrà rilevata e lo script sarà in crash ...

Qui il costruttore del metodo innerJoin:

public function innerJoin($join, $alias, $conditionType = null, $condition = null); 

Potete trovare altre possibilità (e non solo aderire a "ON", ma anche "CON", ecc ...) qui: http://docs.doctrine-project.org/en/2.0.x/reference/query-builder.html#the-expr-class

EDIT

pensa che dovrebbe essere:

$qb->select('c') 
    ->innerJoin('c.phones', 'p', Join::ON, 'c.id = p.customerId') 
    ->where('c.username = :username') 
    ->andWhere('p.phone = :phone'); 

    $qb->setParameters(array(
     'username' => $username, 
     'phone' => $phone->getPhone(), 
    )); 

Altrimenti penso che si sta eseguendo un mix di su e con, forse il problema.

+0

Grazie per averlo indicato. Ma ho incluso lo spazio dei nomi. Ho anche provato a usare direttamente la stringa 'ON'. –

+0

Puoi mostrarci la query completa che scrivi (dall'inizio alla fine)? – Sybio

+0

Ho modificato il post. Grazie! –