Start
Unternehmen
Buch-Katalog
Forschung
Leserservice
Comelio-Blog
Datenbanken
SQL
MS SQL Server
Oracle

Trigger

Module

Pakete

SQLX

SysXMLGen

XDB: Sichten

XDB: XML Schema

XDB: XSLT

XDB: XMLType

XDB: Konzepte

XDB: PL/SQL

XML-Speicheransätze

SQLJ

PHP
UML
C#.NET
XML Schema
XSLT
Business Solutions
Business Intelligence
Software-Technologien
Technologie-Beratung
Individual-Software

Comelio GmbH
Essen
Fon: +49(0)201-437517-0
Fax: +49(0)201-437517-10
info@comelio.com

Comelio GmbH
Berlin
Fon: +49(0)30-3640339-80
Fax: +49(0)30-3640339-89
info@comelio.com

Comelio GmbH
Hamburg
Fon: +49(0)40-20934996-0
Fax: +49(0)40-20934996-9
info@comelio.com

Comelio GmbH
Frankfurt
Fon: +49(0)69-17320683-0
Fax: +49(0)69-17320683-9
info@comelio.com

Comelio GmbH
München
Fon: +49(0)89-38156860-0
Fax: +49(0)89-38156860-9
info@comelio.com

Comelio GmbH
Stuttgart
Fon: +49(0)711-46051275-0
Fax: +49(0)711-46051275-9
info@comelio.com

Comelio GmbH
Leipzig
Fon: +49(0)341-3928790-0
Fax: +49(0)341-3928790-9
info@comelio.com

Comelio GmbH
Köln
Fon: +49(0)221-355337943-0
Fax: +49(0)221-355337943-9
info@comelio.com

Comelio GmbH
Düsseldorf
Fon: +49(0)211-63556420-0
Fax: +49(0)211-63556420-9
info@comelio.com

Comelio-Blog > Oracle > SQLX

XML-Abfragen mit SQLX

Mit dem ISO-Standard SQLX lassen sich relationale Daten aus einer Oracle leicht auch in komplexe XML-Strukturen umwandeln, wobei keine besonderen Voraussetzungen in der Datenbank getroffen werden müssen. Als Vorteil erweist sich gegenüber anderen Techniken, dass es sich letztendlich nur um Spaltenfunktionen handelt. Bei sehr komplexen Abfragen jedoch kann es leicht passieren, dass die Lesbarkeit der Abfragen und damit auch die Erstellung und nachträgliche Arbeit leider durch tiefe Funktionsverschachtelung und entsprechende Klammerung erschwert wird. Dieser Artikel stellt mit verschiedenen Beispielen die vorhandenen Funktionen vor.

Kontakt

Anrede* Herr Frau
Vorname*
Nachname*
Firma
E-Mail*
Tel-Nr.
Bereich*
Freitext

Oracle XDB: XML abfragen

Man muss nicht notwendigerweise Daten in XML gespeichert haben, damit sie auch in XML in der Ergebnismenge vorliegen. Vielmehr bietet Oracle auch einen umfangreichen Funktionsschatz an, mit dem man sowohl Abfragen erstellen kann, die in ihrem Ergebnis aus relationalen Daten XML-Strukturen erzeugen, als auch solche Funktionen erstellen kann, die aus bereits gespeicherten XML-Strukturen Ergebnis-XML-Strukturen erzeugen können. Die Erzeugung von XML-Daten aus einfachen, relationalen Daten soll zunächst in die gesamte XML-Thematik einführen, denn die Verwendung von XML erschließt sich so besonders einfach.

ISO-Standard: SQLX-Funktionen

Die SQLX-Funktionen sind die erste und einfachste Möglichkeit, aus gegebenen relationalen Daten mit Hilfe von Abfragen XML-Daten zu erzeugen. Das Akronym SQLX klingt besonders dramatisch – immerhin ist es auch ein allgemeiner Standard –, allerdings verbirgt es mehr, als es enthüllt. Es handelt sich um einfache Spaltenfunktionen, die zu überaus komplexen Abfragen führen, die aber letztendlich nur die folgenden umfassen:

Funktion Beschreibung
XMLElement () Erzeugt ein Element im Ausgabestrom und nimmt als Werte entweder einen Textknoten (gültiger Spaltenausdruck, fester Vorgabewert) oder weitere Elemente auf.
XMLAttributes() Erzeugt für ein gegebenes Element ein Attribut, das als Wert entweder einen gültigen Spaltenausdruck oder einen festen Wert übernimmt.
XMLForest() Erzeugt mehrere Elemente im Ausgabestrom, besitzt allerdings im Vergleich zu XMLElement()eine verkürzte Syntax.
XMLConcat() Verbindet über Konkatenation alle übergebenen Ausdrücke zu einem XML-Ausdruck. Dabei setzen sich diese Ausdrücke aus einzelnen XMLType-Ausdrücken in Form eines XMLSequenceType-Ausdrucks zusammen, wobei die Funktion als Rückgabewert nur einen einzigen XMLType-Ausdruck liefert.
XMLAGG() Erzeugt aus einer Liste übergebener bzw. abgefragter Reihen, die zusätzlich über ORDER BY und GROUP BY eingerichtet werden können, Kind-Elemente eines Elements. Diese Funktion eignet sich besonders, um Hierarchien korrekt abzubilden und die Form des ursprünglichen relationalen Ergebnisses mit Wiederholungen (z. B. bei Tabellenverknüpfungen) zu vermeiden.
XMLColAttVal() Liefert eine Reihe von Elementen mit dem Namen column, die im name-Attribut den Spaltennamen oder einen vorgegebenen Namen tragen und als Textknoten den Wert enthalten. Diese Funktion eignet sich für die Erzeugung von attributorientiertem Inhalt.

Einfache Abfragen

Die unterschiedlichen Funktionen sind an sich nicht schwer zu verwenden, da ihre Menge ja auch begrenzt ist. Allerdings ist es kompliziert, umfangreiche XML-Dokumente zu erstellen, da die Fehlerhäufigkeit aufgrund der vielen Klammerungen, die vorzunehmen sind, sehr hoch ist. Am einfachsten – wie bei allen SQL-Abfragen – ist es auch hier, zunächst die grundlegende Abfrage auf ihre Richtigkeit zu überprüfen, um dann nachher die passenden XML-Strukturen mit Hilfe der Funktionen zu erzeugen.

Es lohnt sich, die Option SET LONG 200000; in SQL*Plus einzugeben, um die gesamten Zeilen und das gesamte Dokument auch bei längeren Ergebnismengen zu betrachten.

Mit der Funktion XMLElement() lässt sich ein einfaches XML-Element erzeugen. Es übernimmt entweder den Spaltennamen als Namen oder den an erster Stelle übergebenen Namen. Der Ausdruck kann neben weiteren Funktionen ein gültiger Ausdruck sein, um einen (manipulierten) Spaltenwert zu übernehmen oder einen festen Wert auszugeben.

Die allgemeine Syntax ist:

      XMLELEMENT(   elementname IN VARCHAR2,
              [XMLATTRIBUTES(),] 
               value_expr, 
               ...)  
               RETURN XMLType
    

Folgende Abfrage beschafft Kurse und ihre Titelspalten in einer XML-Struktur:

      SELECT XMLElement("Titel", K_Titel || ' ' || K_Untertitel)
  FROM kurs;
    

Man erhält bei dieser Abfrage eine Liste, die in XML nicht einmal korrekt ist, da sie kein Wurzelelement enthält.

      XMLELEMENT("TITEL",K_TITEL||''||K_UNTERTITEL)
<Titel>Perl Module programmieren in Perl</Titel>
<Titel>Perl Programmierung von GUIs mit Perl/Tk</Titel>
…
108 Zeilen ausgewählt.
    

Eine einfache Verschachtelung richtet man daher mit mehreren XMLElement()-Funktionen wie im folgenden Beispiel ein. Dabei werden auch eigene Namen angegeben:

      SELECT XMLElement("Name",
        XMLElement("Titel", K_Titel),
        XMLElement("Untertitel", K_Untertitel))  AS XML
  FROM kurs;
    

Man erhält eine XML-Struktur, die noch ohne Prolog, Schema-Verknüpfungen oder Prozessoranweisungen zurückgeliefert wird. Es ist für die direkte Betrachtung der Daten überaus wichtig, einen passenden oder zumindest kurzen Spaltennamen vorzugeben, da nur eine einzige Spalte über die alles umschließende XMLElement()-Funktion zurückgeliefert wird, sodass ihr eigentlicher Name überaus lang werden kann.

      XML
…
<Name>
  <Titel>Perl</Titel>
  <Untertitel>Syntax + Konzepte</Untertitel>
</Name>
<Name>
  <Titel>Perl</Titel>
  <Untertitel>Perl + CGI</Untertitel>
</Name>
108 Zeilen ausgewählt.
    

Die Abbildung soll noch einmal verdeutlichen, wie die XMLElement()-Funktion arbeitet. Nach der Angabe eines Bezeichners für die Spalte, wobei auch der Wert aus der Datenbank übernommen werden kann, folgt entweder ein gültiger Ausdruck in Form einer Spalte (bzw. einer über andere Spaltenfunktionen manipulierten Spalte) oder eine Auflistung anderer SQLX-Funktionen wie z. B. auch die XMLElement()-Funktion zur Angabe von Kind-Elementen.

Erzeugung von Eltern- und Kind-Elementen

Mit der Funktion XMLAttributes() lassen sich Attribute für ein gegebenes Element erzeugen. Auch hier besteht die Möglichkeit, einen Wert direkt vorzugeben, der stets ausgegeben wird, oder einen anderen gültigen Ausdruck zu verwenden, der sich z. B. auf eine Spalte bezieht.

Die allgemeine Syntax hat die Form:

      XMLATTRIBUTES( value_expr [AS identifier],
               ...) 
               RETURN XMLType
    

Die Abbildung zeigt, wie die Erzeugung von Attributen mit Hilfe der Funktion XMLAttributes() verläuft. Sie wird als optionales Syntax-Element direkt nach der Angabe des Spaltennamens bzw. direkt vor der Angabe des Inhalts für das mit Hilfe der Funktion XMLElement() erzeugte Element verwendet. Mehrere Attribute lassen sich durch eine komma-getrennte Aneinanderreihung von gültigen Ausdrücken in Form von Spaltennamen oder Zeichenketten sowie einem Attributnamen festlegen. Über das Schlüsselwort AS wird hier der Name des Attributs festgelegt.

Erzeugung von Attributen

Mit der Funktion XMLForest() kann man mehrere Kind-Elemente für ein Element erzeugen. Man und spart dabei im Vergleich zu XMLElement()einiges an Quelltext und gewinnt einiges an Übersichtlichkeit, da die entsprechenden Kind-Elemente sehr deutlich durch diese Funktion hervorgehoben werden.

Die allgemeine Syntax hat die Form:

      XMLFOREST( value_expr [AS identifier],
           ...)
           RETURN XMLType
    

Die folgende Abfrage beschafft Teilnehmerinformationen, wobei zur besseren Lesbarkeit Kind-Elemente mit XMLForest() ausgegeben werden:

      SELECT XMLElement("Teilnehmer", XMLAttributes(TN_Nr AS 
                                              "Nr"),
        XMLElement("Name", XMLAttributes(TN_Anrede AS 
                                         "Anrede"),
         XMLForest(TN_Vorname AS "Vorname",
                   TN_Nachname AS "Nachname")),
       XMLElement("Adresse",
        XMLForest(TN_Strasse AS "Straße",
                  TN_Hausnr AS "Hausnr",
                  TN_PLZ AS "PLZ",
                  TN_Stadt AS "Stadt",
                  TN_Stadtteil AS "Stadtteil",
                  TN_Vorwahl||'-'||TN_Telnr AS "Telnr"))),
       XMLElement("Unternehmen", XMLAttributes(U_Nr AS 
                                               "Nr"),
       XMLElement("Name", U_Name),
       XMLElement("Branche", U_Branche),
       XMLElement("Adresse",
        XMLForest(U_Strasse AS "Straße",
                  U_Hausnr AS "Hausnr",
                  U_PLZ AS "PLZ",
                  U_Stadt AS "Stadt",
                  U_Stadtteil AS "Stadtteil",
                  U_Vorwahl||'-'||U_Telnr AS "Telnr"))) AS 
                                                 Buchungen
  FROM teilnehmer  NATURAL JOIN unternehmen WHERE TN_Nr =5;
    

Man erhält:

      BUCHUNGEN
<Teilnehmer Nr="5">
  <Name Anrede="Herr">
    <Vorname>Norbert</Vorname>
    <Nachname>Fahle</Nachname>
  </Name>
  <Adresse>
    <Straße>Steeler Str.</Straße>
    <Hausnr>43</Hausnr>
    <PLZ>44866</PLZ>
    <Stadt>Bochum</Stadt>
    <Stadtteil>Wattenscheid</Stadtteil>
    <Telnr>2327-598187</Telnr>
  </Adresse>
</Teilnehmer>
…
1 Zeile wurde ausgewählt.
    

Komplexe Abfragen

Verknüpft man Tabellen über ihre Primärschlüssel-Fremdschlüssel-Beziehung miteinander, so kehrt man bekanntermaßen den Prozess der Normalisierung um. Dies hat zur Folge, dass man bei entsprechender Sortierung genau die sich wiederholenden Gruppen in der Ergebnismenge erhält, die man ansonsten als Kandidaten für eine eigene Tabelle identifizieren würde. Genau solche Wiederholungen sind natürlich für eine XML-Ausgabe überaus unschön und werden eigentlich niemals benötigt. Mit Hilfe der Funktion XMLAgg() lassen sich solche Gruppen ausschalten. Hierbei können Sie weitere korrelierte Unterabfragen, ORDER BY oder GROUP BY und Kombinationen dieser Syntaxzusätze verwenden.

Die Abbildung veranschaulicht den grundsätzlichen Einsatz der Funktion XMLAgg(). Durch die zusätzliche Gruppierung erhält man nicht eine zusätzliche Ausgabe der allgemeinen Kursinformationen in Form des Titels für jeden Untertitel, sondern tatsächlich nur ein Eltern-Element für den Titel und die Kind-Elemente, die jeden Untertitel beschreiben.

Aggregation für die Verschachtelung

Die XMLAgg()-Funktion erlaubt zusätzlich auch die Verwendung von z. B. korrelierten Unterabfragen. Für die Ermittlung aller Termine eines Titels verwendet man daher eine solche Unterabfrage, die über die Kursnummer in der TERMIN-Tabelle der Unterabfrage mit der gleichen Tabelle der äußeren Abfrage verbunden ist.

      SELECT XMLELEMENT("Kurs", XMLATTRIBUTES(kurs.K_Nr AS "Nr"),
        XMLELEMENT("Titel", K_Titel || ' ' ||  
                   K_Untertitel),
          (SELECT XMLAGG(XMLELEMENT ("Termine",
             XMLELEMENT("Termin", XMLATTRIBUTES(b.T_Nr AS
                                                "Nr"),
               XMLFOREST(T_Beginn AS "Beginn",
                         T_Ende   AS "Ende",
                         T_Ort    AS "Ort"))))
           FROM termin b
          WHERE b.K_Nr = a.K_Nr )) AS XML
  FROM kurs INNER JOIN termin a
    ON kurs.K_Nr = a.K_Nr
 WHERE K_Titel IN ('Oracle', 'Java');
    

Man erhält:

      <Kurs Nr="1015067">
  <Titel>Java Kochrezepte</Titel>
  <Termine>
    <Termin Nr="610">
      <Beginn>14.10.03</Beginn>
      <Ende>17.10.03</Ende>
      <Ort>Bochum</Ort>
    </Termin>
  </Termine>
  …
</Kurs>
149 Zeilen ausgewählt.
    

Die Abbildung soll noch einmal veranschaulichen, wie eine Verschachtelung aufzubauen ist, damit zusätzlich Kind-Elemente von Kind-Elementen und damit tief verschachtelte Strukturen in XML entstehen, die über eine gewöhnliche Abfrage nicht einzurichten wären.

Korrelierte Unterabfrage und Verschachtelung
    Comelio GmbH Oracle: XML mit SQL erzeugen - SQL PL/SQL SQLJ Anleitung Programmierung Datenbank-Entwicklung XML Java Oracle Manual Tutorial PL/SQL -Comelio GmbH Oracle: XML mit SQL erzeugen - SQL PL/SQL SQLJ Anleitung Programmierung Datenbank-Entwicklung XML Java Oracle Manual Tutorial PL/SQL -Comelio GmbH Oracle: XML mit SQL erzeugen - SQL PL/SQL SQLJ Anleitung Programmierung Datenbank-Entwicklung XML Java Oracle Manual Tutorial PL/SQL -Comelio GmbH Oracle: XML mit SQL erzeugen - SQL PL/SQL SQLJ Anleitung Programmierung Datenbank-Entwicklung XML Java Oracle Manual Tutorial PL/SQL -Comelio GmbH Oracle: XML mit SQL erzeugen - SQL PL/SQL SQLJ Anleitung Programmierung Datenbank-Entwicklung XML Java Oracle Manual Tutorial PL/SQL -Comelio GmbH Oracle: XML mit SQL erzeugen - SQL PL/SQL SQLJ Anleitung Programmierung Datenbank-Entwicklung XML Java Oracle Manual Tutorial PL/SQL -Comelio GmbH Oracle: XML mit SQL erzeugen - SQL PL/SQL SQLJ Anleitung Programmierung Datenbank-Entwicklung XML Java Oracle Manual Tutorial PL/SQL -Comelio GmbH Oracle: XML mit SQL erzeugen - SQL PL/SQL SQLJ Anleitung Programmierung Datenbank-Entwicklung XML Java Oracle Manual Tutorial PL/SQL -Comelio GmbH Oracle: XML mit SQL erzeugen - SQL PL/SQL SQLJ Anleitung Programmierung Datenbank-Entwicklung XML Java Oracle Manual Tutorial PL/SQL -