XQuery in Oracle 10g Release 2

Herzlich willkommen

Carsten Czarski

XQuery, der aufkommende W3C-Standard für Abfragen auf XML-Dokumente, wird in der neuen Datenbank Oracle Database 10g Release 2 erstmals unterstützt. XQuery ist eng mit dem Query-Optimizer der Oracle-Datenbank integriert. Eine Standard-Installation reicht für den Einsatz von XQuery völlig aus; zusätzliche Komponenten werden nicht benötigt.

Ziel von XQuery ist es, eine einheitliche Sprache für diverse Aufgaben mit XML-Dokumenten bereitzustellen. Wie Abbildung 1 zeigt, werden Aufgaben wie Recherchen in XML-Dokumenten, XML-Transformationen oder das Generieren von XML bislang mit Technologien wie XPath, XSLT oder SQL/XML umgesetzt. XQuery bringt all diese Anforderungen nun unter ein „sprachliches Dach“ und trägt besonders den Anforderungen großer Dokumentmengen (engl: Collections) oder dem Zusammenführen verschiedenster XML-Datenquellen Rechnung. Gerade hier stößt man bei der Verwendung von XPath bislang schnell an Grenzen.

Der aktuelle Status der XQuery-Spezifikation ist Working Draft. Die endgültige Verabschiedung als Recommendation durch das W3C wird zu Beginn des Kalenderjahrs 2006 erwartet. Die Implementierung in der Oracle-Datenbank orientiert sich daher an einer noch nicht endgültigen Version des Standards. Ergeben sich Änderungen in der endgültigen Version, werden diese mit dem dann folgenden Datenbank-Patchset eingearbeitet.

Anwendungsgebiete für XQuery in einer Datenbank
XQuery an Oracle

Out-of-the-box gibt es zwei Möglichkeiten, XQuery-Abfragen an die Oracle-Datenbank zu übergeben. Zum einen steht im Oracle-Werkzeug SQL*Plus ein XQuery-Interpreter zur Verfügung, zum anderen können XQuery-Ausdrücke durch die Funktionen XMLQUERY und XMLTABLES mit jedem beliebigen SQL-Kommando kombiniert werden. Abfragen, die XML mit relationalen Tabellendaten kombinieren, sind somit kein Problem.

XQuery Interpreter im Oracle SQL*Plus

Gibt man in SQL*Plus das Schlüsselwort XQUERY ein, gelangt man zum XQuery-Interpreter (Abb. 2). Die Abbildung zeigt ein einfaches Hello World-Beispiel in XQuery.

Der folgende Code zeigt die Anwendung der SQL-Funktion XMLQUERY. Der gleiche XQuery-Ausdruck ist nun in ein SQL-Kommando eingebettet, dieses kann auf jedem beliebigen Weg zur Datenbank gelangen – ob JDBC, ODBC oder .NET-Technologie: alles ist möglich.

select 
  xmlquery(
    'for $i in (1,2,3,4) 
     let $j := $i * 2 
     where $i > 2 
     order by $i 
     return Hallo Welt {$j}
    '
    returning content
  )
from dual;
Suche nach XML-Dokumenten mit XQuery

Das naheliegendste Anwendungsbeispiel für XQuery ist die Suche in einer Sammlung (Collection) von XML-Dokumenten. Seit Oracle9i werden XML-Dokumente durch den Datentyp XMLTYPE in der Datenbank repräsentiert. XMLTYPE kann wie jeder andere Datentyp verwendet werden. Eine Collection wird also durch eine XMLTYPE-Tabelle mit XML-Dokumenten repräsentiert. Im Folgenden werden die Beispieldaten der W3C-Spezifikation verwendet. Die XMLTYPE-Tabelle (hier: BIB_TABLE) enthält jeweils ein XML-Dokument für jedes book. Das W3C-Beispiel enthält vier books, die Tabelle speichert somit vier Dokumente, eines davon sieht wie folgt aus:

Data on the WebAbiteboulSergeBunemanPeterSuciuDanMorgan Kaufmann Publishers39.95

Während die beschriebene SQL-Funktion XMLQUERY speziell für XQuery-Operationen auf einzelnen XML-Dokumenten vorgesehen ist, steht für Abfragen auf Collections (also auf Tabellen) die Funktion XMLTABLE zur Verfügung (Listing 1).

Listing 1: XQuery-Abfrage auf Tabellen
----------------------------------------------

select * from xmltable(
'{
for $b in ora:view("BIB_TABLE")/book
where $b/publisher = "Addison-Wesley"
and $b/@year > 1991
return { $b/title }
}'
)
COLUMN_VALUE
--------------------------------------------------------
TCP/IP
IllustratedAdvanced Progra...

1 Zeile ausgewählt.

Mit der Funktion ora:view werden die Inhalte der Tabelle BIB_TABLE in die XQuery-Verarbeitung einbezogen. Das Ergebnis ist ein XML-Dokument, das das Erscheinungsjahr und den Titel derjenigen books enthält, die nach 1991 im Addison-Wesley-Verlag erschienen sind. Mit XML-TABLE lassen sich Collections nicht nur abfragen, sondern auch generieren. Das Beispiel in Listing 2 ruft aus der Tabelle BIB_TABLE Informationen über die Autoren der einzelnen books ab.

Listing 2: Dokument-Collections mit XQuery erzeugen
--------------------------------------------------------------------

select * from xmltable(
'for $a in ora:view("BIB_TABLE")/book/author
return
{ $a/first }{ $a/last }
{$a/../title/text()}'
)
COLUMN_VALUE
-----------------------------------------
W.StevensTCP/IP IllustratedW.
:
5 Zeilen ausgewählt.

Nun wird für jeden Autor ein XML-Dokument zurückgegeben. Sowohl XMLQUERY als auch XMLTABLE geben je nach XQuery-Anfrage einen XMLTYPE oder eine XMLTYPE-Collection zurück. Diese virtuellen XML-Dokumente können anschließend beliebig weiterverarbeitet werden. Eine XSLT-Transformation ist ebenso denkbar wie die Verarbeitung in einer weiteren XQuery-Anweisung. Das in relationalen Datenbanken bekannte Konzept der View ist auch mit XQuery-Abfragen nutzbar. Eine View entsteht, wenn man der SQL-Abfrage einfach die Schlüsselworte create view voranstellt:

create view autoren_xquery as
select xmltable(...

View wurde erstellt.

describe autoren_xquery

 Name                                  Null?              Type
 ------------------------------ -------- ---
 COLUMN_VALUE                                    SYS.XMLTYPE 

Wird die View selektiert, so ergibt sich das gleiche Ergebnis wie in Listing 2. Views eignen sich hervorragend zum „Information Hiding“. Typischerweise wird nur das Leserecht auf eine solche View an einen anderen Datenbankbenutzer vergeben. Für diesen sieht die View aus wie eine Tabelle mit XML-Dokumenten, also wie eine Collection. Die Definition der View ist anderen Nutzern nicht zugänglich.

Von Tabellen zu XML

Nahezu überall besteht die Anforderung, XML-Dokumente aus relationalen Daten zu generieren. Dazu kann nun auch XQuery genutzt werden. Basis für die folgenden Beispiele sind die Tabellen EMP und DEPT im Datenbankschema SCOTT. Die Tabellen enthalten einige Beispieldatensätze und modellieren eine kleine Firma mit vier Abteilungen und 14 Mitarbeitern.

Wiederum zum Einsatz kommt die XQuery-Funktion ora:view. Sie kann auf jede beliebige Tabelle angewendet werden. Relationale Tabellen werden als XML-Dokument mit einfacher, flacher Struktur in die XQuery-Verarbeitung übernommen. Gerade hier sind vielfältige Integrationsszenarien denkbar:

  • Tabellen in entfernten Datenbanken per Datenbank-Link
  • Flache Dateien als externe Tabellen
  • XML-Datenquellen per HTTP

Listing 3 zeigt, wie mit XQuery eine einfache XML-Sicht auf die Tabelle EMP erstellt wird.

Listing 3: Einfache XML-Sicht auf die Tabelle EMP
--------------------------------------------------------

select * from xmltable(
'for $e in ora:view("EMP")/ROW
where $e/SAL/text() > 2000
return $e'
)
COLUMN_VALUE
-------------------------------------------------------
7566JONES
:
7698
:

In der Praxis sind jedoch meist XML-Dokumente mit komplexerer Struktur auf der Basis mehrerer Tabellen gefordert (Listing 4).

Listing 4: Komplexe XML-Sicht mit XQuery
----------------------------------------------------

select * from xmltable(
'for $d in ora:view("DEPT")/ROW
return
{$d/DNAME/text()}
{$d/LOC/text()}
{
for $e in ora:view("EMP")/ROW
where $e/DEPTNO = $d/DEPTNO
order by $e/ENAME/text()
return
{$e/ENAME/text()}{$e/SAL/text()}{$e/HIREDATE/text()}
}
'
)

Wiederum werden die Tabellen mit ora:view eingebunden. In der WHERE-Klausel des XQuery-Ausdrucks werden sie analog zu einem SQL-JOIN (where

psenv::pushli(); eval($_oclass[„e“]); psenv::popli(); ?>

/DEPTNO =

psenv::pushli(); eval($_oclass[„d“]); psenv::popli(); ?>

/DEPTNO) zusammengeführt.

Auch diese XQuery-Abfrage kann als View in der Datenbank hinterlegt werden. Die Inhalte einer solchen XML-View können mit einem beliebigen Browser per HTTP abgerufen werden. Diese Art des Zugriffs funktioniert mit allen Tabellen und Views, wird von der Datenbank selbst bereitgestellt und steht ohne zusätzliche Installation zur Verfügung. Der verwendete URL http://localhost:8080/oradb/SCOTT/EMP_XML wird nach folgendem Schema aufgebaut:

  • http://[host]:[port]
  • Schlüsselwort: /oradb/
  • Datenbank-Benutzer: SCOTT
  • Name der Tabelle oder der View: EMP_XML

Zur Erzeugung von XML-Dokumenten stellt die Oracle-Datenbank damit zwei standardkonforme Sprachen bereit. Neben XQuery können die gleichen Views auch mit den SQL/XML-Funktionen, die zum SQL:2003-Standard gehören, erstellt werden.

XML relational mit XQuery

Je häufiger Informationen im XML-Format vorliegen, desto größer ist die Wahrscheinlichkeit, dass diese Daten von Werkzeugen und Systemen benötigt werden, die nur mit relationalen Daten umgehen können. Dazu ist nur eine kleine Ergänzung im XQuery Sprachkonstrukt notwendig. Listing 5 zeigt, wie die Inhalte von XML-Dokumenten mit XQuery in relationaler Form dargestellt werden.

Listing 5: Relationale Sicht auf XML-Dokumente per XQuery
----------------------------------------------------------------------
select * from xmltable(
'for $a in ora:view("BIB")/book/author
return
{ $a/first }{ $a/last }
{$a/../title/text()}'
columns
first_name varchar2(50) path '/author/first/text()',
last_name varchar2(50) path '/author/last/text()',
book_written varchar2(100) path '/author/book/text()'
) xq
/
FIRST_NAME LAST_NAME BOOK_WRITTEN
---------- ----------------------------------------------
W. Stevens TCP/IP Illustrated
W. Stevens Advanced Programming in ..
Serge Abiteboul Data on the Web
: : :
5 Zeilen ausgewählt.

Die columns-Klausel nach dem XQuery-Ausdruck legt fest, dass das Ergebnis in relationaler Form aufbereitet werden soll. Danach folgen Angaben zu den einzelnen Spalten. Zu jeder Spalte ist ein XPath-Ausdruck vorhanden; dieser navigiert im XQuery-Ergebnis zu dem Knoten, der in der Spalte dargestellt werden soll. Die Angabe von Default-Werten für den Fall, dass der Knoten im XQuery-Ergebnis leer oder nicht vorhanden ist, ist möglich.

Mehr XQuery: Volltextsuche

Insbesondere in Content-Management-Projekten wird fast immer die Anforderung nach Volltextsuche gestellt. Hier werden leider die Grenzen von XQuery deutlich: Die Spezifikation wird auch nach ihrer Verabschiedung keine Syntax für Volltextsuche enthalten. Zwar wird mit den Funktionen contains, starts-with und ends-with Teilstringsuche unterstützt, für Volltextsuche werden jedoch zusätzliche linguistische Funktionen benötigt. Einige Beispiele dafür sind:

  • Suche anhand des Wortstamms: Die Suche nach „Maus“ findet auch die „Mäuse“
  • Ähnlichkeitssuche: Die Suche nach der „Maus“ findet auch die „Maaus“.

In der Oracle-Datenbank wurde für solche Recherchen eine eigene XQuery-Funktion eingeführt. ora:contains grenzt sich wie ora:view durch das Namensraum-Präfix ora von den Funktionen des W3C-Standards ab. Das folgende Beispiel zeigt, wie in einer Tabelle ARTIKEL_ARCHIV nach allen Dokumenten, in denen eine Wortform von „Maus“ vorkommt, gesucht wird.

for $d in ora:view("ARTIKEL_ARCHIV")/artikel
where ora:contains($d/body, "$maus") > 0
return $d

Ist ein Volltextindex vorhanden, wird er zur Ausführung der Volltextrecherche genutzt. Gerade bei großen Dokumentbeständen sollte unbedingt ein Index angelegt werden.

Fazit

Mit der aktuellen Version 10g Release 2 ist die Oracle-Datenbank erstmals in der Lage, XQuery-Anweisungen nativ im Datenbank-Kern auszuführen. Bis zur endgültigen Verabschiedung als Recommendation durch das W3C bietet sich damit eine hervorragende Gelegenheit, XQuery auch anhand von großen Datenbeständen zu testen und mit der Syntax vertraut zu werden.

XQuery lässt jedoch noch einige Wünsche offen. So fehlt die Unterstützung für Volltextsuche und auch für Änderungen an XML-Dokumenten (Update). Trotzdem können Entwickler schon jetzt von XQuery profitieren, da für viele gängige Aufgaben nun eine einheitliche Sprache bereitsteht.

Carsten Czarski arbeitet als Senior-Systemberater bei der ORACLE Deutschland GmbH in der Business Unit Database. Schwerpunkt seiner Tätigkeit ist die Beratung von Kunden und Partnern in Fragen rund um die Oracle-Datenbank.
Geschrieben von
Carsten Czarski
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.