Ausführen von SQL-Anfragen

Der einfachste Weg, eine lesende Datenbankabfrage mit Creole auszuführen, ist die Verwendung der Methode executeQuery($sql) des Connection-Objektes. Diese erwartet die SQL-Anfrage als Parameter und liefert ein ResultSet-Objekt zurück, das die Ergebniszeilen der Abfrage kapselt.

Abbildung 11.3. Die Schnittstelle ResultSet und die Klasse ResultSetIterator

Die Schnittstelle ResultSet und die Klasse ResultSetIterator


Für das Durchlaufen (englisch: Scrolling) der Ergebniszeilen bietet das ResultSet-Objekt die folgenden Methoden an:

Der Zugriff auf die Felder einer Ergebniszeile kann zum einen mit Methoden wie getInt($field) oder getString($code) erfolgen. Zum anderen kann die allgemeine Methode get($field) verwendet werden. Dies ist sinnvoll, falls die automatische Konvertierung des Felddatentyps der Datenbank in einen PHP-Datentyp, wie sie die spezialisierten Methoden bieten, nicht gewünscht ist.

Beispiel 11.2: Lesender Zugriff mit der Methode Connection::executeQuery($sql)

<?php
try {
  $resultSet = $connection->executeQuery(
    'SELECT foo FROM bar;'
  );
 
  while ($resultSet->next()) {
    print $resultSet->getString('foo') . "\n";
  }
}
 
catch (SQLException $e) {
  // Ausnahme $e behandeln.
}
?>


Da das ResultSet-Objekt die Schnittstelle IteratorAggregate (siehe Kapitel 3) anbietet, kann alternativ der foreach-Operator benutzt werden, um die Ergebniszeilen (unter Verwendung eines ResultSetIterator-Objektes) zu verarbeiten.

Beispiel 11.3: Alternative Verwendung des ResultSet-Objektes mit dem foreach-Operator

<?php
try {
  $resultSet = $connection->executeQuery(
    'SELECT foo FROM bar;'
  );
 
  foreach ($resultSet as $rowNumber => $row) {
    printf(
      "%d: %s\n",
 
      $rowNumber,
      $row['foo']
    );
  }
}
 
catch (SQLException $e) {
  // Ausnahme $e behandeln.
}
?>


Analog zu der Methode executeQuery($sql) bietet das Connection-Objekt die Methode executeUpdate($sql) für den schreibenden Zugriff auf die Datenbank an. Die Methode liefert als Rückgabewert die Anzahl der geänderten Zeilen.

In Beispiel 11.4 löschen wir alle Zeilen einer Tabelle mit der Methode executeUpdate($sql).

Beispiel 11.4: Schreibender Zugriff mit der Methode Connection::executeUpdate($sql)

<?php
try {
  $numAffectedRows = $connection->executeUpdate(
    'DELETE FROM bar;'
  );
}
 
catch (SQLException $e) {
  // Ausnahme $e behandeln.
}
?>


Der nächstkomplexere Weg, eine lesende Datenbankabfrage mit Creole auszuführen, besteht in der Verwendung eines Statement-Objektes. In Beispiel 11.5 benutzen wir zunächst die Methode createStatement() des Connection-Objektes, um ein Statement-Objekt zu erzeugen. Auf diesem können wir dann wie gehabt die Methode executeQuery(sql) aufrufen, um ein ResultSet-Objekt mit den Ergebniszeilen zu erhalten.

Abbildung 11.4. Die Creole-Schnittstelle Statement

Die Creole-Schnittstelle Statement


Der Mehraufwand, den das Erzeugen eines Statement-Objektes mit sich bringt, lohnt sich erst dann, wenn die Ergebniszeilen limitiert werden sollen. Beispielsweise lässt sich die MySQL-spezifische Anfrage SELECT foo FROM bar LIMIT 5,10, die maximal 10 Ergebniszeilen (beginnend mit der 6.) liefert, datenbankunabhängig formulieren (wie in Beispiel 11.5 gezeigt).

Beispiel 11.5: Lesender Zugriff mit einem Statement-Objekt

<?php
try {
  $statement = $connection->createStatement();
  $statement->setOffset(5);
  $statement->setLimit(10);
 
  $resultSet = $statement->executeQuery(
    'SELECT foo FROM bar;'
  );
}
 
catch (SQLException $e) {
  // Ausnahme $e behandeln.
}
?>


Für Datenbankabfragen, die dynamisch vor ihrer Ausführung zusammengesetzt werden, sieht Creole die Verwendung von vorbereiteten Anfragen (siehe Kapitel 10) mit einem Objekt der Klasse PreparedStatement vor. Hierbei werden Fragezeichen als Platzhalter im SQL-Code verwendet. Mit Hilfe von Methoden wie setInt($paramIndex, $value) werden diese Platzhalter mit Werten gefüllt.

Abbildung 11.5. Die Creole-Schnittstelle PreparedStatement

Die Creole-Schnittstelle PreparedStatement


In Beispiel 11.6 verwenden wir ein PreparedStatement-Objekt, um mit einer dynamisch erzeugten Anfrage nur ausgewählte Zeilen (WHERE foo = ?) aus der Tabelle zu löschen.

Beispiel 11.6: Schreibender Zugriff mit einem PreparedStatement-Objekt

<?php
$foo = 1978;
 
try {
  $statement = $connection->prepareStatement(
    'DELETE FROM bar WHERE foo = ?;'
  );
 
  $statement->setInt(1, $foo);
 
  $numAffectedRows = $statement->executeUpdate();
}
 
catch (SQLException $e) {
  // Ausnahme $e behandeln.
}
?>


Bietet die verwendete Datenbank native Unterstützung für vorbereitete Anfragen (wie beispielsweise MySQL, siehe Kapitel 10), so wird diese benutzt, um die Verarbeitung der SQL-Anfragen effizienter durchführen zu können.