2016-05-13 23 views
9

My SQL simile a questa:Doctrine - Come associare l'array all'SQL?

$sql = "select * from user where id in (:userId) and status = :status"; 

$em = $this->getEntityManager(); 
$stmt = $em->getConnection()->prepare($sql); 
$stmt->bindValue(':userId', $accounts, \Doctrine\DBAL\Connection::PARAM_INT_ARRAY); 
$stmt->bindValue(':status', 'declined'); 
$stmt->execute(); 

$result = $stmt->fetchAll(); 

ma restituisce:

An exception occurred while executing (...)

with params [[1,2,3,4,5,6,7,8,11,12,13,14], "declined"]

Notice: Array to string conversion

non posso utente queryBuilder perché la mia vera SQL è più complicato (ex contiene unito selezionare, sindacati e così via.)

+0

Puoi usare foreach? 'foreach ($ account come $ chiave => $ val) {$ stmt-> bindValue (': userId', $ val); } ' – pes502

risposta

8

Non è possibile utilizzare le istruzioni preparate con gli array semplicemente perché SQL per sé non supporta gli array. Il che è un vero peccato. Da qualche parte lungo la linea è effettivamente necessario determinare se i dati contengono tre elementi ed emettere un IN (?,?,?). Il gestore dell'entità di Doctrine ORM esegue questa operazione automaticamente.

Fortunatamente, il DBAL ha coperto. Basta non usare legare o preparare. Il manuale ha un esempio: http://doctrine-orm.readthedocs.io/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manipulation.html#list-of-parameters-conversion

Nel tuo caso sarebbe simile:

$sql = "select * from user where id in (?) and status = ?"; 
$values = [$accounts,'declined']; 
$types = [Connection::PARAM_INT_ARRAY, \PDO::PARAM_STRING]; 
$stmt = $conn->executeQuery($sql,$values,$types); 
$result = $stmt->fetchAll(); 

Il codice di cui sopra non è testato, ma si dovrebbe ottenere l'idea.

+0

ok ma in questa situazione devo fare attenzione a legare i dati nel giusto ordine :(Questo è "non bello": \ – breq

+0

Capisco la preoccupazione ei parametri con nome sono carini ma pensaci, hai solo due parametri: non è difficile tenerli in ordine: quando si tratta di query con un numero maggiore di parametri, uso il generatore di query dbal per generare sql e fondamentalmente aggiungere valori al mio array $ values ​​come Quindi non è così male una volta che ci si abitua a esso e ti evita di dover decidere quali nomi devono essere nominati in primo luogo.I nomi sono sempre difficili – Cerad

+0

Ma mu real SQL è più complesso http: // pastebin.com/1JiRHFdc, qualche idea su come fare questo 'giusto'? Conterrà anche più variabili e in cui la clausola se l'utente decide di ottenere più risultati del filtro – breq

-1

È necessario avvolgerli in un array

$stmt->bindValue(':userId', array($accounts), array(\Doctrine\DBAL\Connection::PARAM_INT_ARRAY)); 

http://doctrine-dbal.readthedocs.io/en/latest/reference/data-retrieval-and-manipulation.html#list-of-parameters-conversion

modificare

, avrei elaborato più. Non è possibile associare un array come quello, non preparare lo sql execute direttamente come nell'esempio nei documenti.

$stmt = $conn->executeQuery('SELECT * FROM articles WHERE id IN (?)', 
array(array(1, 2, 3, 4, 5, 6)), 
array(\Doctrine\DBAL\Connection::PARAM_INT_ARRAY)); 

You cannot bind an array of values into a single prepared statement parameter

+1

Io non la penso così ...' Attenzione: PDOStatement :: bindValue() si aspetta che il parametro 3 sia intero, matrice data'. Sto usando il metodo 'prepare', non' executeQuery' – breq

0

Se si vuole attaccare al :param sintassi in cui l'ordine non importa, quello che devi fare un po 'di lavoro extra, ma vi mostrerò un modo più semplice per associare i parametri:

// store all your parameters in one array 
$params = array(
    ':status' => 'declined' 
); 

// then, using your arbitrary array of id's ... 
$array_of_ids = array(5, 6, 12, 14); 

// ... we're going to build an array of corresponding parameter names 
$id_params = array(); 
foreach ($array_of_ids as $i => $id) { 
    // generate a unique name for this parameter 
    $name = ":id_$i"; // ":id_0", ":id_1", etc. 

    // set the value 
    $params[$name] = $id; 

    // and keep track of the name 
    $id_params[] = $name; 
} 

// next prepare the parameter names for placement in the query string 
$id_params = implode(',', $id_params); // ":id_0,:id_1,..." 
$sql = "select * from user where id in ($id_params) and status = :status"; 

in questo caso si finisce con: "select * from user where id in (:id_0,:id_1,:id_2,:id_3) and status = :status"

// now prepare your statement like before... 
$stmt = $em->getConnection()->prepare($sql); 

// ...bind all the params in one go... 
$stmt->execute($params); 

// ...and get your results! 
$result = $stmt->fetchAll(); 

questo approccio funziona anche con un array di stringhe.