sql >> Base de Datos >  >> RDS >> Mysql

La cláusula IN de declaraciones preparadas de PDO con marcadores de posición con nombre no funciona como se esperaba

Esto debería funcionar para usted:

Entonces, como ya se dijo en los comentarios, necesita un marcador de posición para cada valor que desee vincular a la cláusula IN.

Aquí creo primero la matriz $ids que solo contiene los identificadores simples, por ejemplo,

[2, 3]

Luego también creé la matriz $preparedIds que contiene los marcadores de posición como una matriz, que luego usará en la declaración preparada. Esta matriz se parece a esto:

[":id2", ":id3"]

Y también creo una matriz llamada $preparedValues que contiene el $preparedIds como claves y $ids como valores, que luego puede usar para execute() llamar. La matriz se parece a esto:

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

Después de esto, estás listo para irte. En la declaración preparada, simplemente implode() el $preparedIds matriz, de modo que la instrucción SQL se vea así:

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

Y luego puedes simplemente execute() su consulta. Allí solo array_merge() tus $preparedValues matriz con la otra matriz de marcadores de posición.

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

?>

También creo que desea colocar una declaración if alrededor de su consulta, ya que su consulta no se ejecutará si los valores de $timestart y $timeend son NULOS.