Verwenden Sie ein Array in einer vorbereiteten mysqli-Anweisung: `WHERE .. IN(..)`-Abfrage [duplicate]

Lesezeit: 4 Minuten

Benutzer-Avatar
kolypto

Stellen Sie sich vor, wir haben eine Abfrage:

SELECT * FROM somewhere WHERE `id` IN(1,5,18,25) ORDER BY `name`;

und ein Array von IDs zum Abrufen: $ids = array(1,5,18,25)

Bei vorbereiteten Anweisungen empfiehlt es sich, eine Anweisung vorzubereiten und diese mehrmals aufzurufen:

$stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id`=?;');
foreach ($ids as $id){
    $stmt->bind_params('i', $id);
    $stmt->exec();
}

Aber jetzt muss ich die Ergebnisse manuell sortieren. Habe ich schöne Alternativen?

  • Gemäß dem von Ihnen bereitgestellten Link war der Grund für die Erstellung von Anweisungen meiner Meinung nach die Notwendigkeit von UPDATE, das nicht mehrere Aktualisierungen in einer Abfrage unterstützt. Während Sie AUSWÄHLEN und daher Ihre erste Abfrage ausreicht.

    – Ryan Schumacher

    13. September 2010 um 18:30 Uhr

  • Ich war überzeugt, dass vorbereitete Erklärungen in solchen Fällen nicht gut sind. Die einzige nette Lösung besteht darin, eine Abfrage nach oben zu gehen und dieses Array von IDs dort und nicht hier zu sortieren.

    – Kolypto

    14. September 2010 um 1:13 Uhr

Benutzer-Avatar
Clint

Aus meiner Antwort hier kopiert Wie verwende ich PDO-vorbereitete Anweisungen mit IN-Klausel?

mit benannten Platzhaltern

$values = array(":val1"=>"value1", ":val2"=>"value2", ":val2"=>"$value3");
$statement="SELECT * FROM table WHERE `column` in(:".implode(', :',array_keys($values)).') ORDER BY `column`';

mit ??

$values = array("value1", "value2", "$value3");
$statement="SELECT * FROM table WHERE `column` in(".trim(str_repeat(', ?', count($values)), ', ').')  ORDER BY `column`';

  • Ich hatte mit Phalcon damit zu kämpfen, und die untere Option hat es für mich gelöst!

    – krugus

    12. Januar um 15:48 Uhr

du könntest es so machen:

$ids = array(1,5,18,25);

// creates a string containing ?,?,? 
$clause = implode(',', array_fill(0, count($ids), '?'));


$stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id` IN (' . $clause . ') ORDER BY `name`;');

call_user_func_array(array($stmt, 'bind_param'), $ids);
$stmt->execute();

// loop through results

Damit rufen Sie bind_param für jede ID auf und Sie haben die Sortierung mit mysql durchgeführt.

  • Ja, aber das Schlimme ist, dass die Abfrage nicht wiederverwendet werden kann, sodass sie überhaupt nicht vorbereitet werden muss 🙂

    – Kolypto

    13. September 2010 um 18:26 Uhr

  • @o_O Tync: Je weniger Datenbankfahrten, desto besser. Sie können sich gerne an die PreparedStatement-Einschränkungen halten, aber es wird nicht skaliert, wenn Sie 10/20/50/100/1000+ Abfragen für dieselbe Tabelle ausführen müssen.

    – OMG Ponys

    13. September 2010 um 18:30 Uhr


  • Wäre es nicht besser, nur eine Ansicht für diese Anweisung zu erstellen, da sie so oder so nicht wiederverwendet werden könnte?

    – Ryan Schumacher

    13. September 2010 um 18:35 Uhr

  • @Ryan Schumacher: Übersehe ich etwas? Ich sehe nicht, welchen Nutzen eine Ansicht für die Weitergabe von Filterparametern hätte. Es ist nur eine gespeicherte SQL-Anweisung …

    – OMG Ponys

    13. September 2010 um 19:42 Uhr

  • Dies ist in PHP 5.3 aus folgendem Grund problematisch: ca.php.net/manual/en/mysqli-stmt.bind-param.php#96770

    – Levi

    30. Juni 2014 um 6:04 Uhr

Benutzer-Avatar
FabianN.

Hatte das gleiche Problem und zusätzlich zur Antwort von @sled vor 7 Jahren hier eine Möglichkeit ohne das zu machen call_user_func_array(array($stmt, 'bind_param'), $ids); Schritt, aber nur einmal bind_params aufrufen:

$ids = array(1,5,18,25);

// creates a string containing ?,?,? 
$bindClause = implode(',', array_fill(0, count($ids), '?'));
//create a string for the bind param just containing the right amount of iii
$bindString = str_repeat('i', count($ids));

$stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id` IN (' . $bindClause . ') ORDER BY `name`;');

$stmt->bind_params($bindString, ...$ids);
$stmt->execute();

  • Ja, aber das Schlimme ist, dass die Abfrage nicht wiederverwendet werden kann, sodass sie überhaupt nicht vorbereitet werden muss 🙂

    – Kolypto

    13. September 2010 um 18:26 Uhr

  • @o_O Tync: Je weniger Datenbankfahrten, desto besser. Sie können sich gerne an die PreparedStatement-Einschränkungen halten, aber es wird nicht skaliert, wenn Sie 10/20/50/100/1000+ Abfragen für dieselbe Tabelle ausführen müssen.

    – OMG Ponys

    13. September 2010 um 18:30 Uhr


  • Wäre es nicht besser, nur eine Ansicht für diese Anweisung zu erstellen, da sie so oder so nicht wiederverwendet werden könnte?

    – Ryan Schumacher

    13. September 2010 um 18:35 Uhr

  • @Ryan Schumacher: Übersehe ich etwas? Ich sehe nicht, welchen Nutzen eine Ansicht für die Weitergabe von Filterparametern hätte. Es ist nur eine gespeicherte SQL-Anweisung …

    – OMG Ponys

    13. September 2010 um 19:42 Uhr

  • Dies ist in PHP 5.3 aus folgendem Grund problematisch: ca.php.net/manual/en/mysqli-stmt.bind-param.php#96770

    – Levi

    30. Juni 2014 um 6:04 Uhr

Ich werde eine langsame und hässliche Lösung hinzufügen, die dennoch vorbereitete Anweisungen für eine beliebige Anzahl von Array-Elementen verwendet 🙂 3 Anweisungen sind universell für jeden Fall und können überall wiederverwendet werden.

  1. CREATE TEMPORARY TABLE `ids`( `id` INT );
  2. INSERT INTO `ids` VALUES(?); Dadurch werden Ihre IDs eingefügt
  3. SELECT `id` FROM `ids` LEFT JOIN .... ; Verwenden Sie Daten aus anderen Tabellen, um die zu sortieren ids aufführen
  4. SELECT `id` FROM `ids`; wähle alles zurück

Andernfalls müssen Sie verwenden IN (?,?,?,.... oder sortieren Sie die Zeilen manuell. Verwenden Sie am besten einfache MySQL-Abfragen oder versuchen Sie, die Liste der IDs bereits so zu sortieren, wie Sie es möchten.

1008050cookie-checkVerwenden Sie ein Array in einer vorbereiteten mysqli-Anweisung: `WHERE .. IN(..)`-Abfrage [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy