1

I have an array of fields I possibly want to look for in my DB:

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

The number of locations can differ, and I want to create a prepared statement (with Doctrine in Symfony2) that does the same as this:

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

(I think) I know how to use prepared statements in general, like this:

$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');

but how can I do that dynamically if I do not have the size of the array?

Any hint appreciated!

2

3 Answers 3

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

?>
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, I am on the right track, but WHERE start = 1 AND end IN("2,3,5") gives me only one result, whereas WHERE start = 1 AND end IN(2,3,5) gives me all three desired. So instead of converting it to a string, I just use the locations array for the IN statement! Thank you
Fair enough, not too often I use this so a little foggy on it but if you got it working now then all is good. I will update the answer.
@Christian - Please consider editing your answer and remove the first section with the $locationsString. It really opens things up to sql injection attacks. Your second approach is the way to go.
@Cerad, Thanks for the advice. Made the change.
1

@Christian's answer is fine, but just for the sake of completion, you can use foreach in order to create your SQL string.

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

Comments

0

Maybe you are missing 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();

?>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.