Mysql
 sql >> Base de données >  >> RDS >> Mysql

La clause IN des instructions préparées par PDO avec des espaces réservés nommés ne fonctionne pas comme prévu

Cela devrait fonctionner pour vous :

Donc, comme déjà dit dans les commentaires, vous avez besoin d'un espace réservé pour chaque valeur que vous souhaitez lier dans la clause IN.

Ici, je crée d'abord le tableau $ids qui ne contient que les identifiants simples, par exemple

[2, 3]

Ensuite, j'ai également créé le tableau $preparedIds qui contient les espaces réservés sous forme de tableau, que vous utiliserez ensuite plus tard dans l'instruction préparée. Ce tableau ressemble à ceci :

[":id2", ":id3"]

Et je crée également un tableau appelé $preparedValues qui contient les $preparedIds comme clés et $ids comme valeurs, que vous pourrez ensuite utiliser plus tard pour le execute() appel. Le tableau ressemble à ceci :

[":id2" => 2, ":id3" => 3]

Après cela, vous êtes prêt à partir. Dans l'instruction préparée, je viens de implode() les $preparedIds array, de sorte que l'instruction SQL ressemble à ceci :

... IN(:id2,:id3) ...

Et puis vous pouvez simplement execute() votre requête. Là, je viens de array_merge() vos $preparedValues tableau avec l'autre tableau d'espaces réservés.

<?php

    $ids = array_map(function($item){
        return $item->id;
    }, $entitlementsVOs);

    $preparedIds = array_map(function($v){
        return ":id$v";
    }, $ids);

    $preparedValues = array_combine($preparedIds, $ids);


    $timestart = (!empty($_GET['start']) ? $_GET['start'] : NULL );
    $timeend = (!empty($_GET['end']) ? $_GET['end'] : NULL );


    $statement = $this->connection->prepare("SELECT name AS title, timestart AS start, timestart + timeduration AS end FROM event WHERE courseid IN(" . implode(",", $preparedIds) . ") AND timestart >= :timestart AND timestart + timeduration <= :timeend");
    $statement->setFetchMode(\PDO::FETCH_CLASS, get_class(new EventVO()));

    if($statement->execute(array_merge($preparedValues, ["timestart" => $timestart, "timeend" => $timeend]))) {
        return $statement->fetchAll();
    } else {
        return null;
    }

?>

Aussi, je pense que vous voulez mettre une instruction if autour de votre requête, car votre requête ne s'exécutera pas si les valeurs de $timestart et $timeend sont NULL.