Mysql
 sql >> Datenbank >  >> RDS >> Mysql

PDO-vorbereitete Anweisungen IN-Klausel mit benannten Platzhaltern funktionieren nicht wie erwartet

Das sollte für Sie funktionieren:

Wie bereits in den Kommentaren gesagt, benötigen Sie also einen Platzhalter für jeden Wert, den Sie in die IN-Klausel einbinden möchten.

Hier erstelle ich zuerst das Array $ids die nur die einfachen IDs enthält, z. B.

[2, 3]

Dann habe ich auch das Array $preparedIds erstellt die die Platzhalter als Array enthält, die Sie dann später in der vorbereiteten Anweisung verwenden. Dieses Array sieht etwa so aus:

[":id2", ":id3"]

Außerdem erstelle ich ein Array namens $preparedValues die die $preparedIds enthält als Schlüssel und $ids als Werte, die Sie dann später für das execute() verwenden können Anruf. Das Array sieht etwa so aus:

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

Danach können Sie loslegen. In der vorbereiteten Anweisung habe ich nur implode() die $preparedIds Array, sodass die SQL-Anweisung etwa so aussieht:

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

Und dann können Sie einfach execute() ausführen Ihre Anfrage. Dort habe ich einfach array_merge() Ihre $preparedValues array mit den anderen Platzhaltern array.

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

?>

Ich denke auch, dass Sie eine if-Anweisung um Ihre Abfrage setzen möchten, da Ihre Abfrage nicht ausgeführt wird, wenn die Werte von $timestart und $timeend sind NULL.