Tabellendaten als XML im Browser: einfach so!
Vor einiger Zeit hatte ich ja mal ein kleines Tutorial zum Thema XML erzeugen mit den SQL/XML-Funktionen veröffentlicht. Damit ist es möglich, Tabellendaten in beliebiger Art und Weise als XML aufzubereiten.
Aber wusstet Ihr schon, dass Ihr XML auch völlig ohne Code generieren könnt ...?
Seit Oracle9i gibt es das DB URI Servlet und die DB URI Types. Und das lässt sich ganz einfach nutzen. Zuerst solltet Ihr prüfen, ob der HTTP-Listener eurer Datenbank aktiv ist. Das geschieht ganz einfach mit einem lsnrctl status.
$ lsnrctl status
LSNRCTL for Linux: Version 11.1.0.7.0 - Production on 27-MAY-2009 19:57:37
Copyright (c) 1991, 2008, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.2.140)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 11.1.0.7.0 - Production
Start Date 27-MAY-2009 19:49:19
Uptime 0 days 0 hr. 8 min. 18 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /oracle/u01/app/oracle/product/11.1.0/network/admin/listener.ora
Listener Log File /oracle/u01/app/oracle/diag/tnslsnr/vmware/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.2.140)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=vmware.de.oracle.com)(PORT=8081))(Presentation=HTTP)(Session=RAW))
Services Summary...
Service "orcl.doag.org" has 1 instance(s).
Instance "orcl", status READY, has 2 handler(s) for this service...
Service "orclXDB.doag.org" has 1 instance(s).
Instance "orcl", status READY, has 3 handler(s) for this service...
Service "orcl_XPT.doag.org" has 1 instance(s).
Instance "orcl", status READY, has 2 handler(s) for this service...
The command completed successfully
Wenn die rote Zeile bei euch nicht vorhanden ist, müsst Ihr den HTTP-Listener erst aktivieren. Das geht bei 11g-Datenbanken mit der Prozedur DBMS_XDB.SETHTTPPORT oder auch bei älteren Datenbanken mit dem SQL-Skript $ORACLE_HOME/rdbms/admin/catxdbdbca.sql. Nehmt einen TCP/IP-Port eurer Wahl; mit dem Port "0" wird der HTTP-Listener abgeschaltet.
Nun könnt Ihr Tabellendaten als XML abrufen. Startet einen Browser und gebt mal folgende URL ein, umdie Daten der EMP-Tabelle zu betrachten.
http://[database-host]:[http-port]/oradb/SCOTT/EMP
Ihr werdet zunächst aufgefordert, euch einzuloggen; nehmt einen Datenbankuser, der die Tabelle EMP lesen kann (naheliegenderweise SCOTT). Daraufhin solltet Ihr in etwa folgendes Ergebnis sehen.
Die XML-Struktur ist in diesem Fall vorgegeben; sie kann nicht beeinflusst werden. Aber im Gegenzug generiert die Datenbank ohne viel Aufwand XML aus den Tabellendaten. Wenn Ihr eigene XML-Strukturen benötigt, sind wir wieder bei den eingangs erwähnten SQL/XML-Funktionen. Und in manchen Fällen reicht diese einfache XML-Struktur vielleicht sogar aus ...
Ihr könnt die Ansicht auch mit Kriterien beschränken; dazu wird XPath-Syntax verwendet. Aber Achtung; das DB URI Servlet unterstützt nicht die komplette XPath-Syntax, nur ein Subset kann verwendet werden. Die XML-Funktionen in der Datenbank wie EXTRACTVALUE oder EXISTSNODE unterstützen XPath dagegen vollständig. So zeigt die folgende URL nur eine Zeile aus der EMP-Tabelle an.
http://[host]:[port]/oradb/SCOTT/EMP/ROW[EMPNO=7839]
Auch andere Kriterien sind möglich; wenn mehrere Zeilen selektiert werden, ist jedoch ein zusätzlicher Parameter rowsettag nötig, sonst gibt es eine Fehlermeldung.
http://[host]:[port]/oradb/SCOTT/EMP/ROW[JOB="CLERK"]?rowsettag=QUERY
Mit der Funktion SYS_DBURIGEN könnt Ihr euch URLs generieren lassen. Damit wird es möglich, auf eine bestimmte Tabellenspalte in einer bestimmten Zeile mit genau einer Zeichenkette, eben der URI zu verweisen.
SQL> select sys_dburigen(ENAME, SAL) from partner.emp where empno=7844;
SYS_DBURIGEN(ENAME,SAL)(URL, SPARE)
--------------------------------------------------------------------------------
DBURITYPE('/PARTNER/EMP/ROW[ENAME=''TURNER'']/SAL', NULL)
Setzt man nun Hostname und Port und das Schlüsselwort oradb davor, so kann man sich das Ergebnis im Browser ansehen ... aber auch in SQL können diese URI verwendet werden. Dazu gibt es den Objekttypen DBURITYPE.
SQL> select dburitype('/PARTNER/EMP/ROW[ENAME=''TURNER'']/SAL').getxml() from dual;
DBURITYPE('/PARTNER/EMP/ROW[ENAME=''TURNER'']/SAL').GETXML()
--------------------------------------------------------------------------------
<?xml version="1.0"?>
<SAL>1501</SAL>
Probiert es mal aus ... insbesondere die Variante über den Browser kann sehr interessant sein. Wenn man nun noch berücksichtigt, dass Kommandozeilenwerkzeugen wie wget es erlauben, diese Funktionalität in Batchläufen zu nutzen, dann wird es sehr einfach, XML von der Datenbank in andere Systeme zu übertragen. Einfacher geht es nun wirklich nicht ...
Mehr Informationen zu den DB URIs findet Ihr im XML DB Handbuch. Darin enthalten sind auch Informationen über zusätzliche HTTP-Parameter, die Ihr verwenden könnt - so kann transform eine XSLT-Transformation auslösen ... schaut einfach mal rein.