sql >> Databáze >  >> RDS >> Mysql

Klauzule IN připravená PDO s pojmenovanými zástupnými symboly nefunguje podle očekávání

Toto by vám mělo fungovat:

Jak již bylo řečeno v komentářích, potřebujete zástupný symbol pro každou hodnotu, kterou chcete svázat do klauzule IN.

Zde nejprve vytvořím pole $ids který obsahuje pouze prosté ID, např.

[2, 3]

Poté jsem také vytvořil pole $preparedIds který obsahuje zástupné symboly jako pole, které pak později použijete v připraveném příkazu. Toto pole vypadá asi takto:

[":id2", ":id3"]

A také vytvořím pole nazvané $preparedValues který obsahuje $preparedIds jako klíče a $ids jako hodnoty, které pak můžete později použít pro execute() volání. Pole vypadá nějak takto:

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

Poté můžete jít. V připraveném příkazu jsem jen implode() $preparedIds pole, takže příkaz SQL bude vypadat nějak takto:

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

A pak můžete jednoduše execute() váš dotaz. Tam jsem jen array_merge() vaše $preparedValues pole s polem ostatních zástupných symbolů.

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

?>

Také si myslím, že chcete kolem svého dotazu umístit příkaz if, protože váš dotaz se nespustí, pokud hodnoty $timestart a $timeend jsou NULL.




  1. Jak zabezpečit MySQL:Část první

  2. PHP - MySQL připravilo příkaz pro INSERT pole

  3. Automatické generování Doctrine-Entity z existující tabulky

  4. Jak snížit duplicitu kódu způsobenou podřetězcem a řetězcem?