Mehrfach-Anweisungen
Bei MySQL ist es optional möglich, mehrere Anweisungen in einer Anweisungszeile zu haben, was aber eine besondere Vorgehensweise erfordert.
Mehrfach-Anweisungen oder Mehrfach-Abfragen müssen mit mysqli::multi_query() ausgeführt werden. Die einzelnen Anweisungen der Anweisungszeile werden durch Semikolon getrennt. Anschließend müssen alle Ergebnismengen, die von den ausgeführten Anweisungen zurückgegeben werden, abgerufen werden.
Der MySQL-Server erlaubt es, Anweisungen, die Ergebnismengen zurückgeben, und Anweisungen, die keine Ergebnismengen zurückgeben, in einer Mehrfach-Anweisung zu verwenden.
Beispiel #1 Mehrere Anweisungen
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$sql = "SELECT COUNT(*) AS _num FROM test;
INSERT INTO test(id) VALUES (1);
SELECT COUNT(*) AS _num FROM test; ";
$mysqli->multi_query($sql);
do {
if ($result = $mysqli->store_result()) {
var_dump($result->fetch_all(MYSQLI_ASSOC));
$result->free();
}
} while ($mysqli->next_result());
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
array(1) { [0]=> array(1) { ["_num"]=> string(1) "0" } } array(1) { [0]=> array(1) { ["_num"]=> string(1) "1" } }
Sicherheitstechnische Überlegungen
Die API-Funktionen mysqli::query() und
mysqli::real_query() setzen kein Verbindungsflag auf
dem Server, das für die Aktivierung von Mehrfach-Abfragen benötigt wird.
Für Mehrfach-Anweisungen wird ein zusätzlicher API-Aufruf verwendet, um den
Schaden von Angriffen mit SQL-Injections zu verringern. Ein Angreifer
könnte versuchen, Anweisungen wie ; DROP DATABASE mysql
oder ; SELECT SLEEP(999)
an das Ende einer Anweisung
anzuhängen. Wenn es dem Angreifer gelingt, SQL zur Anweisung hinzuzufügen,
aber mysqli::multi_query
nicht verwendet wird, führt der
Server die eingeschleuste bösartige SQL-Anweisung nicht aus.
Beispiel #2 SQL-Injection
<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
$result = $mysqli->query("SELECT 1; DROP TABLE mysql.user");
if (!$result) {
echo "Fehler beim Ausführen der Abfrage: (" . $mysqli->errno . ") " . $mysqli->error;
}
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Fehler beim Ausführen der Abfrage: (1064) You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DROP TABLE mysql.user' at line 1
Vorbereitete Anweisungen
Die Verwendung der Mehrfach-Anweisung wird bei vorbereiteten Anweisungen nicht unterstützt.
Siehe auch