sql >> データベース >  >> RDS >> Mysql

名前付きプレースホルダーを含むPDOプリペアドステートメントのIN句が期待どおりに機能しない

    これはあなたのために働くはずです:

    したがって、コメントですでに述べたように、IN句にバインドする値ごとにプレースホルダーが必要です。

    ここでは、最初に配列$idsを作成します プレーンIDのみを保持します。例:

    [2, 3]
    

    次に、配列$preparedIdsも作成しました これはプレースホルダーを配列として保持し、後でプリペアドステートメントで使用します。この配列は次のようになります:

    [":id2", ":id3"]
    

    また、$preparedValuesという配列も作成します。 $preparedIdsを保持します キーおよび$idsとして 値として、後でexecute()に使用できます 電話。配列は次のようになります:

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

    この後、あなたは行ってもいいです。プリペアドステートメントでは、implode()だけです。 $preparedIds 配列。SQLステートメントは次のようになります。

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

    そして、あなたは単にexecute()することができます あなたのクエリ。そこで私はarray_merge() $preparedValues 他のプレースホルダー配列との配列。

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

    また、$timestartの値の場合、クエリは実行されないため、クエリの前後にifステートメントを配置することをお勧めします。 および$timeend NULLです。




    1. 同期フレームワーク:Oracle / SQLServer

    2. 複数のレコードを続けて表示する

    3. BLOBイメージPHPMySQLを他のデータと一緒に表示する

    4. java.sql.SQLException:不正な文字列値:'\ xF0 \ x9F \ x91 \ xBD \ xF0 \ x9F ...'