Variablen mit XML-Inhalt

Comelio-Blog MS SQL Server Variablen mit XML-InhaltErstellt man eine Abfrage, welche XML-Werte zurückliefert, dann erhält man als Ergebnis Werte im Datentyp xml. Diese können dann direkt in einer Variablen oder für einen Rückgabewert einer Funktion genutzt werden. Dieser besondere Datentyp verhält sich wie jeder andere, weil er überall dort auftauchen kann, wo auch ein anderer Datentyp genutzt werden kann. Zum Beispel als Datentyp für eine Variable oder einen Rückgabewert.

XML Variablen und Spalten

Erstellt man eine Abfrage, welche XML-Werte zurückliefert, dann erhält man als Ergebnis Werte im Datentyp xml. Diese können dann direkt in einer Variablen oder für einen Rückgabewert einer Funktion genutzt werden. Dieser besondere Datentyp verhält sich wie jeder andere, weil er überall dort auftauchen kann, wo auch ein anderer Datentyp genutzt werden kann. Zum Beispel als Datentyp für eine Variable oder einen Rückgabewert.

Der Datentyp xml hat als einziger Datentyp, der von T-SQL vorgeben ist, einen so genannten Konstruktor. Dies ist ein optionaler Klammerausdruck, mit dem Werte definiert werden können. Dadurch wird sichergestellt, dass nicht nur XML-Daten genutzt werden, sondern dass diese Daten auch gültig für ein Schema, d.h. für ein Regeldokument sind. In der Dokumentation wird XML zwichen typisiertem und nicht-typisiertem XML unterschieden.

Eine nicht-typisierte XML-Variable soll erstellt und über eine Abfrage mit Werten gefüllt werden. Dazu gibt es zunächst zwei Variablen productXML und productChar welche als xml und nvar-char(max) deklariert werden. Mit der Syntax SELECT @variable = spalte kann man Werte aus einer Spalte abrufen. Welche Spalten in den Variablen gespeichert werden sollen, kann genau festgelegt werden, da andere Spalten unberücksichtigt bleiben.

Bei der Umwandlung von Zeichenketten in XML und zurück kann man zwischen den beiden Funktionen CAST und CONVERT wählen. Wichtig ist bei der Umwandlung in XML, den richtigen Wert für den optionalen style-Parameter von CONVERT zu verwenden.

CAST ( expression AS data_type [ (length ) ])
CONVERT ( data_type [ ( length ) ] , expression [ , style ] )

Nachfolgend eine Liste mit den möglichen style Parametern für die Funktion convert.

  • Der Standartwert 0 löscht bedeutungslose Zeichenketten und lässt keine interne DTD-Teilmenge zu. Keine Angabe der Document Type Defintion ist zulässig.
  • Mit dem Parameterwert 1 verbleiben bedeutungslose Zeichenketten im Dokument. Dies bedeutet, dass das XML-Standardattribut xml:space, welches immer verwendet werden darf, den Wert preserve (Leerzeichen erhalten) besitzt
  • 2 legt fest, dass interne DTD-Teilmengen - Document Type Definition-Angaben - mit einfachen Regeln berücksichtigt werden. Standardwerte für Attribute werden aus der DTD in das XML übernommen. Selbst erstellte, interne Entitäten werden aus der DTD in das XML kopiert und schließlich wird eine Syntaxüberprüfung durchgeführt. Externe DTD-Teilmengen werden nicht beachtet.
  • 3 bedeutet, dass bedeutungslose Leerzeichen erhalten bleiben und dass - wie beim Parameterwert 2 - die begrenzte DTD-Verarbeitung durchgeführt wird

Nachfolgend ein Beispiel um zu zeigen, wie einfach die Umwandlung ist. Es wird zwischen beiden Variablen konvertiert und schließlich das Ergebnis mit PRINT oder mit SELECT ausgegeben.

DECLARE @productXML xml, @productChar nvarchar(max)
SET @productXML = (
SELECT TOP 30 Name,
       ProductNumber,
       ListPrice
  FROM Production.Product
 ORDER BY ProductID DESC
FOR XML PATH('Product'), ROOT('Product-List'))
SET @productChar = CONVERT(nvarchar(max), @productXML)
SET @productXML = CAST(@productChar AS xml)
PRINT @productChar

Darüber hinaus kann man, anstelle vom Abruf der XML-Daten aus einer Abfrage, die Vollständige oder teilweise Erstellung von XML-Daten als Zeichenkette beuntzen. Jenes ist zum Beispiel notwendig, wenn die XML-Datei nicht aus einer sehr umpfangreichen Abfrage stammt, sondern aus mehreren einzelnen Abfragen erstellt und schließlich zusammengesetzt wird. Durch einfaches Erstellung einer Zeichenkette mit dem XML-typischen Tag-Zeichen < und >, kann dieser Lösungsansatz umgesetzt werden. Die Umwandlung geshieht hier wahlweise mit einen der beiden vorgestellten Funktionen CAST oder CONVERT.

Neben der Speicherung von XML in einer Variablen ist es ebenfalls zulässig, Spalten von (temporären) Tabellen oder Variablen, die mit table erstellt wurden, mit dem Datentyp xml auszustatten. Die aus einer Zeichenkette erzeugte XML-Datei wird daher in einer mit table erstellten Tabelle gespeichert, wobei an dieser Stelle auch temporäre oder gewöhnliche DB-Tabellen genutzt werden können. Diese Daten lassen sich dann wieder mit einem ganz gewöhnlichen SELECT abrufen, wobei in diesem Fall beim Abruf auch noch eine Umwandlung in eine Zeichenkette erfolgen soll, was jedoch nicht notwendig ist, sondern nur beispielhaft vorgeführt wird.

DECLARE @productXML xml, @productChar nvarchar(max)
DECLARE @xmlTable table(nr int, product xml)
SET @productXML = CONVERT(xml, N'<Product-List> 
<Product> <Name> Road-750 Black, 52</Name> 
<ProductNumber> BK-R19B-52</ProductNumber> 
<ListPrice>539.9900</ListPrice></Product></Product-List> ')
INSERT INTO @xmlTable	
VALUES (1, @productXML)
SELECT @productChar = CAST(product AS nvarchar(max))
  FROM @xmlTable
PRINT @productChar

Die Speicherung von XML Dateien in Tabellen ist ebenfalls möglich. Im zurückliegenden Script wurde eine Variable in einem gewöhnlichen INSERT-Befehl aufgerufen. Als weiter Lösung, hätte man auch eine XML-Zeichenkette nach XML umgewandelt können. Letztens kann man die Daten einer Abfrage, welche XML generiert, direkt in einer INSERT-Anweisung - also ohne Varibale - aufzurufen. Diese Abfrage wird in zwei runden Klammern plaziert.

CREATE TABLE #xmlTable(nr int, product xml)
INSERT INTO #xmlTable
SELECT 1, (SELECT  TOP 30 
		 Name,
                   ProductNumber,
                   ListPrice
              FROM Production.Product
               FOR XML PATH('Product'), ROOT('Product-List'))
SELECT CAST(product AS nvarchar(max)) FROM #xmlTable

Eine weitere Möglichkeit ist der Zugriff auf eine XML Datei im Dateisystem. Die Lösung dieses Problemes ist die Anweisung OPENROWSET, welche eigentlich für den Massenimport aus Textdateien gedacht ist. Ihre Anwendung ist zwar in T-SQL-Programmen hinterlegt, aber die Benutzung wird im Buch zur Administration beschrieben. Die allgemeine Syntax soll hier reichen, da dies ansonsten viel zu umpfangreich würde.

OPENROWSET 
( BULK 'data_file' , 
       { FORMATFILE = 'format_file_path' [ <bulk_options> ]
       | SINGLE_BLOB | SINGLE_CLOB | SINGLE_NCLOB } )

Im Wesentlichen besteht die Anweisung aus OpenRowset und der BULK-Klausel, welche für eine beliebige XML-Datei im Dateisystem gilt und die Form eines SINGLE_BLOB darstellt. auch hier ist eine Umwandlung von Nöten.

DECLARE @productXML xml
SELECT @productXML = CAST(textFile AS xml)
FROM OpenRowset(BULK 'c:/products.xml',
                SINGLE_BLOB) C(textFile)
SELECT @productXML

»Kontaktformular










comelio.com

  • Comelio GmbH
    Berlin
    Fon: +49(0)30-8145622-00
    Fax: +49(0)30-8145622-10
  • Comelio GmbH
    München
    Fon: +49(0)89-38156860-0
    Fax: +49(0)89-38156860-9
  • Comelio GmbH
    Hamburg
    Fon: +49(0)40-20934996-0
    Fax: +49(0)40-20934996-9
  • Comelio GmbH
    Wien
    Fon: +43-720-2097-97
    Fax: +43-720-2097-98