Oracle mit PHP verwenden
Kommentare

Fragen über Fragen – Abfragen gegen eine Oracle-Datenbank sind mit das Einfachste

Bei vorhandener Verbindung wird die Abfrage zunächst für die weitere Verwendung vorbereitet (oci_parse) und anschließend ausgeführt (oci_execute). Aus dem Ergebnis können dann mit oci_fetch_* die jeweiligen Daten geholt werden. Nach Abschluss der Abfrage geben wir noch mit oci_free_statement den Speicher frei (Listing 7).

<?php .
$stmt = oci_parse($conn, 'SELECT LAST_NAME, FIRST_NAME, PHONE_NUMBER 
                            FROM EMPLOYEES 
                           ORDER BY LAST_NAME ASC');
oci_execute($stmt);

while ($row = oci_fetch_assoc($stmt)) {
    printf('%s, %s: %s
',
        $row['LAST_NAME'],
        $row['FIRST_NAME'],
        $row['PHONE_NUMBER']);
}

oci_free_statement($stmt);
.
?>
Ergebnis
Abel, Ellen: 011.44.1644.429267
Ande, Sundar: 011.44.1346.629268
Atkinson, Mozhe: 650.124.6234
Austin, David: 590.423.4569
Baer, Hermann: 515.123.8888
Baida, Shelli: 515.127.4563
...
Wichtig ist die Behandlung von LOB-Objekten (BLOB, CLOB). Während das in MySQL ganz normal wie bei anderen Datentypen auch funktioniert, muss man Oracle mit speziellen Befehlen die LOB-Daten entlocken. Um das zu verdeutlichen, erzeugen wir zunächst eine einfache Tabelle, fügen einen Beispieldatensatz ein und versuchen den Inhalt mit PHP wieder auszulesen (Listing 8).
CREATE TABLE LOB_TABLE
(
  LOB_COL CLOB
);

INSERT INTO LOB_TABLE (LOB_COL) VALUES ('foo bar');

.

<?php .
$stmt = oci_parse($conn, 'SELECT LOB_COL FROM LOB_TABLE');
oci_execute($stmt);

while ($row = oci_fetch_assoc($stmt)) {
    printf('%s
', $row['LOB_COL']);
}
.
?>
Ergebnis: Ein Fehler – PHP Catchable fatal error: Object of class OCI-Lob could not be converted to string in … Wenn wir uns das Ergebnis per var_dump ausgeben lassen, wird alles klar (Listing 9).
array(1) {
  ["LOB_COL"]=>
  object(OCI-Lob)#1 (1) {
    ["descriptor"]=>
    resource(4) of type (oci8 descriptor)
  }
}
Hier wird nicht der Wert selbst, sondern eine Ressource auf ein Objekt vom Typ OCI-Lob zurückgeben. Wir müssen also mit speziellen LOB-Methoden auf den Inhalt zugreifen (Listing 10).
<?php ...
printf('%s
', $row['LOB_COL']->load());
.
?>

foo bar
Wichtig: Im Anschluss müssen diese LOB-Objekte wieder freigegeben werden. Hierzu verwendet man die Methode OCI-Lob->free().

Überschreiten der Höchstgeschwindigkeit

Wenn man nun sehr viele Abfragen verwendet, wird man sich danach sehnen, diese Abfragen zu beschleunigen. Jetzt kann man natürlich versuchen, die Datenbank oder die SQL-Abfragen zu optimieren, um einen Geschwindigkeitszuwachs zu erreichen. Diese und weitere gängige Methoden, z. B. die Vermeidung von Full Table Scans etc., sind mit Sicherheit sinnvoll. Aber es gibt die Möglichkeit mit Bind-Variablen/Prepared Statements zu arbeiten. Bei jeder Abfrage wird im Cache nachgesehen, ob die Abfrage bereits existiert. Wenn nicht, muss Oracle diese parsen und analysieren, im Cache speichern und dann die Daten auslesen. Bei vielen ähnlichen Abfragen ist dieser Prozess natürlich sehr zeitaufwändig. Bind-Variablen stellen die Möglichkeit bereit, eine Query sozusagen zu abstrahieren:
SELECT LAST_NAME, JOB_ID FROM EMPLOYEES WHERE JOB_ID = 'SH_CLERK';
SELECT LAST_NAME, JOB_ID FROM EMPLOYEES WHERE JOB_ID = 'SA_REP';
SELECT LAST_NAME, JOB_ID FROM EMPLOYEES WHERE JOB_ID = 'AD_PRES';
Diese Abfragen unterscheiden sich lediglich durch die JOB_ID im WHERE-Bereich. Das lässt sich hervorragend optimieren (Listing 11).
$stmt  = oci_parse($conn, 'SELECT LAST_NAME, JOB_ID FROM EMPLOYEES WHERE JOB_ID = :JOB_ID');

$jobId = 'SH_CLERK';

oci_bind_by_name($stmt, 'JOB_ID', $jobId);

oci_execute($stmt);
Wir ersetzen die Angabe der JOB_ID durch einen Platzhalter (:JOB_ID), und „befüllen“ diesen mit der Funktion oci_bind_by_name(). Wie üblich analysiert und speichert Oracle die Abfrage nun. Bei der nächsten Abfrage wird Oracle aber vor der Analyse im Cache fündig, holt sich hier die bereits analysierte Abfrage und befüllt sie vor Ausführen der Abfrage mit den variablen Daten. Ganz nebenbei haben wir hier auch eine wunderbare Möglichkeit, uns vor SQL-Injections zu schützen.

Fazit

Wie man sieht, ist Oracle gar nicht so mysteriös, wie man vielleicht denken mag. Nach der Lektüre dieses Artikels sollte der Leser ohne Weiteres in der Lage sein, Oracle-basierte Anwendungen zu entwickeln und dabei die Untiefen zu umschiffen. Weiterführende Informationen gibt es im Web mehr als genug, einige Links sind am Ende dieses Artikels aufgelistet. Ganz besonders möchte ich nochmal auf das Underground PHP and Oracle Manual (PDF) verweisen und mich an dieser Stelle ausdrücklich bei dessen Autoren Christopher Jones und Allison Holloway bedanken. Jason Easter ist seit 2006 bei der Mayflower GmbH in Würzburg tätig. Er arbeitet dort als Teamleiter und Senior Developer. In seiner Freizeit organisiert er die PHP Usergroup Würzburg. Alle Teile: Teil 1, Teil 2, Teil 3, Teil 4, Teil 5, Teil 6
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -