Matthias Apsel: PDO bindParam

Hallo alle,

siehe auch: T1755284

ich habe folgende vereinfacht dargestellte Situation:

$foo = "1,2,3,4";
$stmt = $db -> prepare("SELECT `col` FROM `table`
                        WHERE `ID` IN (:foo)");
$stmt -> bindValue(':foo',$foo);

Nach einem execute erhalte ich jedoch keine Datensätze. Ich vermute, das liegt daran, dass die Query

SELECT `col` FROM `table` WHERE `ID` IN ('1,2,3,4')

statt

SELECT `col` FROM `table` WHERE `ID` IN (1,2,3,4)

erzeugt wird.

Gibt es dafür eine Lösung.

Das beschriebene Verhalten kann ich mit php-myadmin nachstellen. Heißt auch, dass die zweite Query die gewünschten Datensätze liefert.

Bis demnächst
Matthias

--
Pantoffeltierchen haben keine Hobbys.
¯\_(ツ)_/¯

akzeptierte Antworten

  1. Tach!

    Nach einem execute erhalte ich jedoch keine Datensätze. Ich vermute, das liegt daran, dass die Query

    SELECT `col` FROM `table` WHERE `ID` IN ('1,2,3,4')
    

    statt

    SELECT `col` FROM `table` WHERE `ID` IN (1,2,3,4)
    

    erzeugt wird.

    Ja, es wird immer nur ein Wert gebunden. Und $foo ist ein String.

    Gibt es dafür eine Lösung.

    Für jeden Wert einen eigenen Platzhalter verwenden.

    Beim PDOStatement::execute() ist das auch bestätigt: Multiple values cannot be bound to a single parameter; for example, it is not allowed to bind two values to a single named parameter in an IN() clause.

    dedlfix.

    1. Hallo dedlfix,

      Ich hab mir jetzt so geholfen:

      $stmt = $db -> query("SELECT `col` FROM `table` WHERE `ID` IN ($foo)");
      

      Aber schön ist das irgendwie nicht. Interessant, dass es an anderer Stelle genau so funktioniert hat. Ich muss gleich mal testen, ob das nur aufgrund meiner Testdaten so war.

      Bis demnächst
      Matthias

      --
      Pantoffeltierchen haben keine Hobbys.
      ¯\_(ツ)_/¯
      1. Tach!

        Aber schön ist das irgendwie nicht.

        Anders geht es nicht, weil dann nicht klar wird, ob der Wert als Skalar behandelt werden soll oder auf irgendeine Weise zerpflückt werden muss.

        Nun könnte man argumentieren, dass bei Übergabe eines Arrays das PDO die Aufteilung vornimmt und das Statement im Nachhinein ändert. Das wäre dann aber eine Ausnahme und Abweichung vom Üblichen. Und das würde auch nur bei simulierten Prepared Statements gehen, weil ansonsten das Statement ja bereits im DBMS ist.

        dedlfix.

      2. Hallo Matthias Apsel,

        Interessant, dass es an anderer Stelle genau so funktioniert hat. Ich muss gleich mal testen, ob das nur aufgrund meiner Testdaten so war.

        Es war nur aufgrund meiner Testdaten.

        Bis demnächst
        Matthias

        --
        Pantoffeltierchen haben keine Hobbys.
        ¯\_(ツ)_/¯
  2. Hallo Matthias Apsel,

    die Lösung findet sich unter https://stackoverflow.com/questions/14767530/php-using-pdo-with-in-clause-array

    $arr = [1,2,3];
    $in = implode(',', array_fill(0, count($arr), '?'));
    $sql = "SELECT * FROM tab WHERE foo=? AND col IN ($in) AND bar=? AND baz=?";
    $stmt = $db -> prepare($sql);
    $params = array_merge([$foo], $arr, [$bar, $baz]);
    $stmt -> execute($params);
    $data = $stmt -> fetchAll();
    

    Danke auch noch mal an @dedlfix.

    Bis demnächst
    Matthias

    --
    Pantoffeltierchen haben keine Hobbys.
    ¯\_(ツ)_/¯