2015-10-26 3 views
1

У меня есть массив полей я, возможно, нужен искать в моей БД:Подготовленное Заявление с переменным массивом

$locations = array(
     2,3,5 
    ); 

Количество мест может отличаться, и я хочу, чтобы создать подготовленное заявление (с доктриной в Symfony2), что делает то же самое, как это:

SELECT * FROM locations WHERE start = 1 AND (end = 2 OR end = 3 OR end = 5) 

(я думаю) Я знаю, как использовать подготовленные заявления, в общем, как это:

$query = $em->createQuery(
    'SELECT l 
    FROM AppBundle:Location l 
    WHERE l.start > :start 
    AND (l.end = :end1 
    OR l.end = :end2 
    OR l.end = :end3) 
    ORDER BY l.duration ASC' 
) 
->setParameter('start', '1') 
->setParameter('end1', '2') 
->setParameter('end2', '3') 
->setParameter('end3', '5'); 

но как я могу сделать это динамически, если у меня нет размера массива?

Любой намек оценили!

+0

На MySQl есть функция IN, которая позволяет вам проверять массивы. – Christian

+0

похоже на: http://stackoverflow.com/questions/17589626/symfony2-3-raw-sql-query-with-in-clause и http://stackoverflow.com/questions/5929036/how-to-use- where-in-with-doctrine-2 – Terminus

ответ

2
<?php 
$locations = array(
    2,3,5 
); 

$query = $em->createQuery(
    'SELECT l 
    FROM AppBundle:Location l 
    WHERE l.start > :start 
    AND l.end IN :end 
    ORDER BY l.duration ASC' 
) 
->setParameter('start', '1'); 
->setParameter('end', $locations); 

?> 
+0

Спасибо, я нахожусь на правильном пути, но 'WHERE start = 1 AND end IN (" 2,3,5 ")' дает мне только один результат, тогда как 'WHERE start = 1 И конец IN (2,3,5) 'дает мне все три желания. Поэтому вместо того, чтобы преобразовать его в строку, я просто использую массив местоположений для инструкции IN! Спасибо – PrimuS

+0

Достаточно честный, не слишком часто я использую это так немного туманно, но если вы сейчас это работаете, тогда все хорошо. Я обновлю ответ. – Christian

+0

@Christian - попробуйте отредактировать свой ответ и удалите первый раздел с помощью $ locationsString. Это действительно открывает вещи для SQL-инъекций. Ваш второй подход - это путь. – Cerad

1

@ ответ христианина это хорошо, но только ради завершения, вы можете использовать foreach для того, чтобы создать свой SQL строку.

<?php 
$locations = array(2, 3, 5); 
$endQueries = []; 

foreach ($locations as $i => $location) { 
    $endQueries[] = "l.end = :end{$i}"; 
} 

$queryString = 'SELECT l 
FROM AppBundle:Location l 
WHERE l.start > :start 
AND (' . implode(' OR ', $endQueries) . ') 
ORDER BY l.duration ASC'; 

$query = $em->createQuery($queryString); 
$query->setParameter("start", '1'); 

foreach ($locations as $i => $location) { 
    $query->setParameter("end{$i}", $location); 
} 
0

Возможно, вам не хватает fetchAll?

<?php 
$locations = array(
    2,3,5 
); 

$query = $em->createQuery(
    'SELECT l 
    FROM AppBundle:Location l 
    WHERE l.start > :start 
    AND l.end IN :end 
    ORDER BY l.duration ASC' 
) 
->setParameter('start', '1'); 
->setParameter('end', $locations); 

/* == Added a fetchAll call == */ 
$query->execute->fetchAll(); 

?> 
Смежные вопросы