Mysql
 sql >> Database >  >> RDS >> Mysql

Le istruzioni PDO preparate nella clausola IN con segnaposto denominati non funzionano come previsto

Questo dovrebbe funzionare per te:

Quindi come già detto nei commenti è necessario un segnaposto per ogni valore che si vuole associare alla clausola IN.

Qui creo prima l'array $ids che contiene solo gli ID semplici, ad es.

[2, 3]

Quindi ho anche creato l'array $preparedIds che contiene i segnaposto come matrice, che in seguito utilizzerai nell'istruzione preparata. Questo array assomiglia a questo:

[":id2", ":id3"]

E creo anche un array chiamato $preparedValues che contiene il $preparedIds come chiavi e $ids come valori, che in seguito potrai utilizzare per execute() chiamata. L'array assomiglia a questo:

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

Dopo questo sei a posto. Nella dichiarazione preparata ho appena implode() il $preparedIds array, in modo che l'istruzione SQL assomigli a questa:

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

E poi puoi semplicemente execute() la tua domanda. Lì ho solo array_merge() i tuoi $preparedValues array con l'altro array di segnaposto.

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

?>

Inoltre penso che tu voglia inserire un'istruzione if attorno alla tua query, poiché la tua query non verrà eseguita se i valori di $timestart e $timeend sono NULL.