Oracle mit PHP verwenden
Kommentare

Gruppenspiele für Datenbanken: Äußerst interessant sind auch die Unterschiede bei scheinbar einfachen, „normalen“, standardkonformen Abfragen.

Wenn man z. B. das durchschnittliche Gehalt je Beruf wissen möchte, funktioniert das in MySQL problemlos (Listing 4).

SELECT J.JOB_TITLE, AVG(E.SALARY)
  FROM EMPLOYEES E
  LEFT OUTER JOIN (JOBS J)
    ON (E.JOB_ID = J.JOB_ID)
 GROUP BY E.JOB_ID
Ergebnis
JOB_TITLE AVG(E.SALARY)
1 Public Accountant 8300.000000
2 Accounting Manager 12000.000000
3 Administration Assistant 4400.000000
4 President 24000.000000
5 Administration Vice President 17000.000000
N
Oracle wirft da den Fehler ORA-00979. Eine Abfrage auf ora-code.com (bzw. http://FEHLERNUMMER.ora-code.com/) nennt folgenden Grund:
The GROUP BY clause does not contain all the expressions in the SELECT clause. SELECT expressions that are not included in a group function, such as AVG, COUNT, MAX, MIN, SUM, STDDEV, or VARIANCE, must be listed in the GROUP BY clause.
Oracle hat also ein Problem damit, dass wir nicht anhand der Berufsbezeichnung gruppieren, sondern stattdessen die JOB_ID verwenden. Sobald wir JOB_TITLE in GROUP BY aufgenommen haben, funktioniert alles wie gewünscht:
SELECT J.JOB_TITLE, AVG(E.SALARY)
  FROM EMPLOYEES E
  LEFT OUTER JOIN (JOBS J)
    ON (E.JOB_ID = J.JOB_ID)
 GROUP BY E.JOB_ID, J.JOB_TITLE
Eine immer wieder gern verwendete Funktion für die gruppierte Ausgabe von Inhalten in einer Textspalte ist GROUP_CONCAT (Listing 5).
SELECT GROUP_CONCAT(REGION_NAME ORDER BY REGION_NAME SEPARATOR ', ')
  FROM REGIONS
Ergebnis
GROUP_CONCAT(REGION_NAME SEPARATOR ‚, ‚)
1 Europe, Americas, Asia, Middle East and Africa
Unglücklicherweise kennt Oracle diese Funktion nicht, lässt sich aber trotzdem dazu bewegen, die gewünschten Daten auszugeben (Listing 6).
SELECT RTRIM(
  XMLAGG(
    XMLELEMENT(c, REGION_NAME || ', ') ORDER BY REGION_NAME).EXTRACT('//text()'), ','
  ) AS CONCATENATED
FROM REGIONS

Anbindung an PHP

Der Zugriff auf die Daten wird sich natürlich nicht auf Spielereien mit dem Oracle SQL Developer beschränken. Viel mehr interessiert uns hier das Zusammenspiel mit PHP. Die Anbindung kann auf verschiedene Arten erfolgen, aus Gründen der Perfomanz werden wir hier auf in PHP geschriebene Abstraktionslayer verzichten. Als Erstes wäre die altbekannte Oracle-Extension zu erwähnen. Diese Erweiterung (php_oracle.dll) war Bestandteil von PHP 3 bis 5. Sie stellte nur eingeschränkte Funktionalitäten zur Verfügung und ist kein Bestandteil mehr von aktuellen PHP-Distributionen. php_oracle.dll wird logischerweise auch nicht mehr weiterentwickelt und sollte auch nicht für neue Softwareprojekte verwendet werden. Die OCI8-Extension (php_oci8.dll bzw. php_oci8_11g.dll) ist ebenfalls seit Version 3 in PHP enthalten und wird auch Bestandteil von Version 6 sein. Oracle selbst hat ständig ein Auge auf diese Erweiterung und kümmert sich um die kontinuierliche Weiterentwicklung. In PHP 5.3 ist eine für Oracle 11g optimierte Extension enthalten. Die PDO-Extension für Oracle (php_pdo_oci.dll) wäre eine dritte Alternative. Sie ist von PHP allerdings als experimentell gekennzeichnet und bietet auch nicht den Funktionsumfang wie OCI8. Als vierte Möglichkeit ist noch Zend Core for Oracle zu nennen. Es handelt sich hier um ein vorgefertigtes Release von Zend, in dem die entsprechenden Erweiterungen bereits aktiviert sind. Ebenfalls enthalten ist ein Apache Webserver, der optional mitinstalliert werden kann. Zend hat sich bewusst dazu entschieden, nicht die aktuellste Version der OCI8-Extension zu verwenden, sondern auf eine ältere, dafür aber ausführlich getestete Version zurückzugreifen. Wen das und der Umstand, dass es immer etwas länger dauert, bis die nächste PHP-Version in Zend Core integriert wird, nicht stört, und wer lieber die Gewissheit haben möchte, dass er ein perfekt auf das Zusammenspiel von Oracle und PHP-optimiertes Paket verwendet, das vom jeweiligen Hersteller zertifiziert wurde, ist hier natürlich am besten beraten – zumal Zend Core for Oracle kostenlos ist. Ich persönlich tendiere dazu, direkt mit der OCI8-Extension zu arbeiten. Seit ungefähr zwei Jahren existiert diese in Version 1.3 (php_oci8_11g.dll), die stabil läuft und signifikante Performancegewinne mit sich bringt und darüber hinaus auch noch die neuesten Features von Oracle 11 unterstützt. Am interessantesten ist hier die Verwendung des Database Resident Connection Pooling (DRCP). DRCP ist seit Oracle 11g verfügbar, Voraussetzung in PHP ist also, dass auch der Oracle Instant Client in Version 11 installiert wurde. Ohne DRCP wird bei jeder von PHP etablierten Verbindung zu Oracle ein Prozess gestartet, der nach dem Ende des Skripts wieder zerstört wird. Die Verwendung persistenter Verbindungen schafft hier Abhilfe, indem Verbindungen offen gehalten werden, selbst wenn diese gerade nicht benötigt werden. Das geht jedoch zu Lasten der Performanz. DRCP stellt nun, vereinfacht dargestellt, mehrere Serverprozesse bereit, die von mehreren Anwendungen untereinander aufgeteilt werden können. Wenn ein PHP-Skript nun eine Verbindung zu Oracle benötigt, kommuniziert dieses solange mit dem Connection Broker, bis die Verbindung beendet wird. Das erfolgt entweder automatisch, wenn das Skript beendet wurde, oder kann explizit durch den Aufruf von oci_close() erfolgen. Nach Verbindungsende wird der Datenbankprozess wieder im Pool abgelegt. Den höchsten Geschwindigkeitszuwachs erhält man, wenn man keine persistenten Verbindungen einsetzt, da diese nach der Verwendung gleich wieder freigegeben werden. Wann sollte man nun DRCP einsetzen? Auf jeden Fall, wenn man Anwendungen mit sehr vielen Datenbankverbindungen betreibt und nur wenig Speicher vergeben möchte. Aber auch wenn man mit immer denselben Zugangsdaten auf Oracle zugreift, ist ein Pooling sinnvoll. Die Anwendung greift nur kurz auf eine Datenbankverbindung zu und gibt diese wieder frei? Auch hierfür kann DRCP angebracht sein. Wenn man DRCP nicht einsetzen kann, sollte man auf jeden Fall immer persistente Verbindungen aufbauen, sodass einmal geöffnete Verbindungen für eine gewisse Zeit vorgehalten werden. Ohne persistente Verbindungen wird für jede benötigte Verbindung zuerst ein neuer Datenbankprozess gestartet und anschließend eine Authentifizierung durchgeführt. Erst dann werden die Abfragen ausgeführt und anschließend der Prozess wieder beendet. Das alles ist bei Oracle sehr zeitaufwändig, Abfragen könnten so mitunter mehrere Sekunden dauern. Weiter mit: Teil 6 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 -