OPENXML (SQL Server)

Gilt für:SQL ServerAzure SQL-DatenbankAzure SQL Managed Instance

OPENXML ist ein Transact-SQL-Schlüsselwort, das ein Rowset über XML-Dokumente im Arbeitsspeicher bereitstellt, die einer Tabelle oder Ansicht ähneln. OPENXML ermöglicht den Zugriff auf XML-Daten, als ob es sich um ein relationales Rowset handeln würde. Dies geschieht, indem eine Rowsetsicht der internen Darstellung eines XML-Dokuments bereitgestellt wird. Die Datensätze im Rowset können in Datenbanktabellen gespeichert werden.

OPENXML kann immer dann in SELECT- und SELECT INTO-Anweisungen verwendet werden, wenn Rowsetanbieter, eine Sicht oder OPENROWSET als Quelle verwendet werden können. Informationen zur Syntax von OPENXML finden Sie unter OPENXML (Transact-SQL).For information about the syntax of OPENXML, see OPENXML (Transact-SQL).

Um Abfragen für XML-Dokumente mithilfe von OPENXML zu schreiben, müssen Sie zunächst sp_xml_preparedocumentaufrufen. Dies analysiert das XML-Dokument und gibt ein Handle auf das analysierte Dokument zurück, das zur Verwendung bereit ist. Das analysierte Dokument ist eine strukturierte Dokumentobjektdarstellung (DOM - Document Object Model) der verschiedenen Knoten des XML-Dokuments. Das Dokumenthandle wird an OPENXML übergeben. OPENXML erstellt dann auf der Grundlage der übergebenen Parameter eine Rowsetsicht des Dokuments.

Hinweis

sp_xml_preparedocument verwendet eine SQL-aktualisierte Version des MSXML-Parsers (Msxmlsql.dll). Diese Version des MSXML-Parsers wurde entwickelt, um SQL Server zu unterstützen und abwärtskompatibel mit MSXML Version 2.6 zu bleiben.

Die interne Darstellung eines XML-Dokuments muss durch einen Aufruf der gespeicherten Systemprozedur sp_xml_removedocument aus dem Arbeitsspeicher gelöscht werden, um den Arbeitsspeicher zu leeren.

Der Vorgang wird in der folgenden Abbildung veranschaulicht.

Parsing XML with OPENXML.

Um die Funktionsweise von OPENXML zu verstehen, benötigen Sie Kenntnisse über XPath-Abfragen und XML. Weitere Informationen zur XPath-Unterstützung in SQL Server finden Sie unter Verwenden von XPath-Abfragen in SQLXML 4.0.

Hinweis

Mit OpenXML können die XPath-Muster für die Zeilen und Spalten als Variablen parametrisiert werden. Diese Art der Parametrisierung kann zu XPath-Ausdrucksangriffen führen, wenn der Programmierer die Parametrisierung für externe Benutzer offen legt (wenn Parameter beispielsweise über eine extern aufgerufene gespeicherte Prozedur bereitgestellt werden). Um solche potenziellen Sicherheitsprobleme zu vermeiden, sollten XPath-Parameter niemals für externe aufrufende Prozesse offen gelegt werden.

Beispiel

Das folgende Beispiel veranschaulicht die Verwendung von OPENXML in einer INSERT - und einer SELECT -Anweisung. Das XML-Beispieldokument setzt sich aus <Customers> - und <Orders> -Elementen zusammen.

Zuerst analysiert die gespeicherte Prozedur sp_xml_preparedocument das XML-Dokument. Das analysierte Dokument ist eine strukturierte Darstellung der Knoten im XML-Dokument (Elemente, Attribute, Text und Kommentare). OPENXML verweist dann auf dieses analysierte XML-Dokument und erstellt eine Rowsetansicht für das gesamte oder Teile des XML-Dokuments. Eine INSERT -Anweisung kann mithilfe von OPENXML Daten aus einem solchen Rowset in eine Datenbanktabelle einfügen. Es können mehrere OPENXML -Aufrufe verwendet werden, um eine Rowsetsicht verschiedener Teile des XML-Dokuments bereitzustellen und sie zu verarbeiten, indem sie z. B. in unterschiedliche Tabellen eingefügt werden. Dieses Verfahren wird auch als Aufteilen von XML-Daten in Tabellen bezeichnet.

Im folgenden Beispiel wird ein XML-Dokument so aufgeteilt, dass mithilfe von zwei <Customers> -Anweisungen Customers -Elemente in der <Orders> -Tabelle und Orders -Elemente in der INSERT -Tabelle gespeichert werden. Das Beispiel enthält auch eine SELECT -Anweisung mit OPENXML , die CustomerID und OrderDate aus dem XML-Dokument abruft. Der letzte Schritt in diesem Verfahren besteht darin, sp_xml_removedocumenterneut aufzurufen. Dadurch wird der der internen XML-Darstellung, die während der Analysephase erstellt wurde, zugewiesene Arbeitsspeicher freigegeben.

-- Create tables for later population using OPENXML.
CREATE TABLE Customers (CustomerID varchar(20) primary key,
                ContactName varchar(20),
                CompanyName varchar(20));
GO
CREATE TABLE Orders( CustomerID varchar(20), OrderDate datetime);
GO
DECLARE @docHandle int;
DECLARE @xmlDocument nvarchar(max); -- or xml type
SET @xmlDocument = N'<ROOT>
<Customers CustomerID="XYZAA" ContactName="Joe" CompanyName="Company1">
<Orders CustomerID="XYZAA" OrderDate="2000-08-25T00:00:00"/>
<Orders CustomerID="XYZAA" OrderDate="2000-10-03T00:00:00"/>
</Customers>
<Customers CustomerID="XYZBB" ContactName="Steve"
CompanyName="Company2">No Orders yet!
</Customers>
</ROOT>';
EXEC sp_xml_preparedocument @docHandle OUTPUT, @xmlDocument;
-- Use OPENXML to provide rowset consisting of customer data.
INSERT Customers
SELECT *
FROM OPENXML(@docHandle, N'/ROOT/Customers')
  WITH Customers;
-- Use OPENXML to provide rowset consisting of order data.
INSERT Orders
SELECT *
FROM OPENXML(@docHandle, N'//Orders')
  WITH Orders;
-- Using OPENXML in a SELECT statement.
SELECT * FROM OPENXML(@docHandle, N'/ROOT/Customers/Orders')
  WITH (CustomerID nchar(5) '../@CustomerID', OrderDate datetime);
-- Remove the internal representation of the XML document.
EXEC sp_xml_removedocument @docHandle;

Die folgende Abbildung zeigt die analysierte XML-Struktur des vorherigen XML-Dokuments, das mithilfe von sp_xml_preparedocument erstellt wurde.

Parsed XML tree.

OPENXML-Parameter

Zu den Parametern für OPENXML gehören:

  • Ein XML-Dokumenthandle (idoc)

  • Ein XPath-Ausdruck zur Identifizierung der Knoten, die Zeilen zugeordnet werden (rowpattern)

  • Eine Beschreibung des zu generierenden Rowsets

  • Die Zuordnung zwischen den Rowsetspalten und den XML-Knoten

XML-Dokumenthandle (idoc)

Das Dokumenthandle wird von der gespeicherten Prozedur sp_xml_preparedocument zurückgegeben.

XPath-Ausdruck zum Identifizieren der zu verarbeitenden Knoten (Rowpattern)

Der als rowpattern angegebene XPath-Ausdruck bezeichnet einen Knotensatz im XML-Dokument. Jeder von rowpattern identifizierte Knoten entspricht in dem von OPENXML generierten Rowset einer einzelnen Zeile.

Bei den durch den XPath-Ausdruck identifizierten Knoten kann es sich um jeden im XML-Dokument enthaltenen Knoten handeln. Wenn rowpattern eine Reihe von Elementen im XML-Dokument identifiziert, gibt es eine Zeile im Rowset für jeden identifizierten Elementknoten. Wenn z. B. rowpattern mit einem Attribut endet, wird für jeden von rowpatternausgewählten Attributknoten eine Zeile erstellt.

Beschreibung des zu generierenden Rowsets

Zum Generieren des Rowsets verwendet OPENXML ein Rowsetschema. Ein Rowsetschema kann über die folgenden Optionen angegeben werden.

Verwenden des Randtabellenformats

Um ein Rowsetschema anzugeben, müssen Sie das Rahmentabellenformat verwenden. Verwenden Sie die WITH-Klausel nicht.

In diesem Fall gibt OPENXML ein Rowset im Rahmentabellenformat zurück. Die Bezeichnung Rahmentabelle geht darauf zurück, dass jeder Rahmen in der analysierten XML-Dokumentstruktur einer Zeile im Rowset zugeordnet wird.

Rahmentabellen stellen die detaillierte XML-Dokumentstruktur in einer einzigen Tabelle dar. Diese Struktur enthält die Element- und Attributnamen, die Dokumenthierarchie, die Namespaces und die Verarbeitungsanweisungen. Mit dem Randtabellenformat können Sie zusätzliche Informationen abrufen, die nicht über die Metaeigenschaften verfügbar gemacht werden. Weitere Informationen zu Metaeigenschaften finden Sie unter Specify Metaproperties in OPENXML.

Die von Rahmentabellen gebotenen zusätzlichen Informationen ermöglichen Ihnen das Speichern und Abfragen des Datentyps eines Elements oder Attributs, des Knotentyps sowie das Speichern und Abfragen von Informationen zur Struktur von XML-Dokumenten. Die zusätzlichen Informationen ermöglichen außerdem das Erstellen eines eigenen XML-Dokumentmanagementsystems.

Mithilfe einer Rahmentabelle können Sie gespeicherte Prozeduren schreiben, die XML-Dokumente als BLOB-Eingabe (Binary Large OBject) verwenden, die Rahmentabelle ausgeben und dann das Dokument auf einer detaillierteren Ebene extrahieren und analysieren. Diese detaillierte Ebene kann die Dokumenthierarchie, die Element- und Attributnamen, die Namespaces und die Verarbeitungsanweisungen enthalten.

Die Randtabelle kann auch als Speicherformat für XML-Dokumente dienen, wenn die Zuordnung zu anderen relationalen Formaten nicht logisch ist und ein ntext-Feld nicht genügend strukturelle Informationen bereitstellt.

Wenn die Überprüfung des XML-Dokuments mit einem XML-Parser möglich ist, können Sie dieselben Informationen stattdessen auch mit einer Rahmentabelle erhalten.

In der folgenden Tabelle wird die Struktur der Rahmentabelle (edge) beschrieben.

Spaltenname Datentyp BESCHREIBUNG
id bigint Die eindeutige ID des Dokumentknotens.

Das Stammelement weist den ID-Wert 0 auf. Die negativen ID-Werte sind reserviert.
parentid bigint Identifiziert das übergeordnete Element des Knotens. Das durch diese ID identifizierte übergeordnete Element ist nicht unbedingt das übergeordnete Element. Dies hängt jedoch vom NodeType des Knotens ab, dessen übergeordnetes Objekt durch diese ID identifiziert wird. Wenn es sich bei dem Knoten beispielsweise um einen Textknoten handelt, kann das übergeordnete Objekt ein Attributknoten sein.

Wenn sich der Knoten auf der obersten Ebene im XML-Dokument befindet, ist ParentID gleich NULL.
node type int Identifiziert den Knotentyp. Eine ganze Zahl, die der Nummer des Knotentyps des XML-Objektmodells (DOM) entspricht.

In dieser Spalte können folgende Werte den Knotentyp angeben:

1 = Elementknoten

2 = Attributknoten

3 = Textknoten

4 = CDATA-Abschnittsknoten

5 = Entitätsverweisknoten

6 = Entitätsknoten

7 = Verarbeitungsanweisungsknoten

8 = Kommentarknoten

9 = Dokumentknoten

10 = Dokumenttypknoten

11 = Dokumentfragmentknoten

12 = Notationsknoten

Weitere Informationen finden Sie im Artikel "nodeType Property" im Microsoft XML (MSXML)-SDK.
localname nvarchar(max) Gibt den lokalen Namen des Elements oder Attributs an. Ist NULL, wenn das DOM-Objekt keinen Namen hat.
Präfix nvarchar(max) Das Namespacepräfix des Knotennamens.
namespaceuri nvarchar(max) Der Namespace-URI (Universal Resource Identifier) des Knotens. Ist der Wert NULL, ist kein Namespace vorhanden.
datatype nvarchar(max) Der eigentliche Datentyp der Element- oder Attributzeile, der anderenfalls NULL ist. Der Datentyp wird aus der Inline-DTD (Document Type Definition) oder aus dem Inlineschema abgeleitet.
prev bigint Die XML-ID des vorhergehenden gleichgeordneten Elements. Ist NULL, wenn kein direktes gleichgeordnetes Gleichgeordnetes vorhanden ist.
text ntext Enthält den Attributwert oder den Elementinhalt als Text. Oder ist NULL, wenn der Randtabelleneintrag keinen Wert benötigt.

Verwenden der WITH-Klausel zum Angeben einer vorhandenen Tabelle

Mit der WITH-Klausel können Sie den Namen einer vorhandenen Tabelle angeben. Hierzu geben Sie einfach den Namen einer vorhandenen Tabelle an, deren Schema OPENXML zum Generieren des Rowsets verwenden kann.

Verwenden der WITH-Klausel zum Angeben eines Schemas

Mit der WITH-Klausel können Sie ein vollständiges Schema angeben. Ein Rowsetschema wird durch Angeben der Spaltennamen, der zugehörigen Datentypen und der Zuordnung zum XML-Dokument angegeben.

Sie können das Spaltenmuster mithilfe des ColPattern-Parameters in SchemaDeclaration angeben. Das angegebene Spaltenmuster wird zur Zuordnung einer Rowsetspalte zum von rowpattern bezeichneten XML-Knoten und zur Bestimmung des Zuordnungstyps verwendet.

Wenn "ColPattern" für eine Spalte nicht angegeben ist, wird die Rowsetspalte dem XML-Knoten mit demselben Namen zugeordnet, basierend auf der durch den Flags-Parameter angegebenen Zuordnung. Wenn ColPattern in der WITH-Klausel jedoch als Teil der Schemaspezifikation angegeben ist, wird die im flags -Parameter angegebene Zuordnung überschrieben.

Zuordnung zwischen den Rowsetspalten und den XML-Knoten

In der OPENXML-Anweisung können Sie optional den Typ der Zuordnung – wie attributzentriert oder elementzentriert – zwischen den Rowsetspalten und den von rowpatternidentifizierten XML-Knoten angeben. Diese Information wird bei der Transformation zwischen XML-Knoten und Rowsetspalten verwendet.

Die Zuordnung kann auf zwei Arten angegeben werden, wobei Sie auch beide angeben können:

  • Mit dem flags -Parameter

    Die vom flags -Parameter angegebene Zuordnung geht von einer Namensentsprechung aus, bei der die XML-Knoten den entsprechenden Rowsetspalten mit demselben Namen zugeordnet werden.

  • Mit dem ColPattern -Parameter

    ColPattern, ein XPath-Ausdruck, wird in der WITH-Klausel als Teil von SchemaDeclaration angegeben. Durch die in ColPattern angegebene Zuordnung wird die Zuordnung des flags -Parameters überschrieben.

    ColPattern kann zur Angabe des Zuordnungstyps – wie attributzentriert oder elementzentriert – verwendet werden, der die vom Parameter flagsangegebene Standardzuordnung überschreibt oder erweitert.

    ColPattern wird in folgenden Situationen angegeben:

    • Der Spaltenname im Rowset unterscheidet sich vom Element- oder Attributnamen, dem er zugeordnet ist. In diesem Fall wird ColPattern zur Identifizierung des XML-Element- und Attributnamens verwendet, dem die Rowsetspalte zugeordnet ist.

    • Der Spalte soll ein Metaeigenschaftsattribut zugeordnet werden. In diesem Fall wird ColPattern zur Identifizierung der Metaeigenschaft verwendet, der die Rowsetspalte zugeordnet ist. Weitere Informationen zur Verwendung von Metaeigenschaften finden Sie unter Angeben von Metaeigenschaften in OPENXML.

Sowohl der flags -Parameter als auch der ColPattern -Parameter sind optional. Wenn keine Zuordnung angegeben ist, wird eine attributzentrierte Zuordnung vorgenommen. Die attributzentrierte Zuordnung ist der Standardwert des flags -Parameters.

Attributorientierte Zuordnung

Wenn der flags -Parameter in OPENXML auf 1 festgelegt ist (XML_ATTRIBUTES), wird die attributzentrierte Zuordnung durchgeführt. Wenn flags XML_ATTRIBUTES enthält, enthält oder verwendet das verfügbar gemachte Rowset Zeilen, in denen jedes XML-Element als eine Zeile dargestellt ist. Die XML-Attribute werden den Attributen zugeordnet, die in der SchemaDeclaration definiert sind oder die vom TableName der WITH-Klausel basierend auf der Namenskorrespondenz bereitgestellt werden. Die Namensübereinstimmung bedeutet, dass XML-Attribute eines bestimmten Namens in einer Spalte im Rowset mit demselben Namen gespeichert werden.

Wenn sich der Spaltenname vom zugeordneten Attributnamen unterscheidet, muss der ColPattern -Parameter angegeben werden.

Wenn das XML-Attribut über einen Namespacequalifizierer verfügt, muss der Spaltenname im Rowset ebenfalls über einen Qualifizierer verfügen.

Elementzentrierte Zuordnung

Wenn der flags -Parameter in OPENXML auf 2 (XML_ELEMENTS) festgelegt ist, wird die elementzentrierte Zuordnung vorgenommen. Es ähnelt der attributorientierten Zuordnung, mit Ausnahme der folgenden Unterschiede:

  • Die Namensübereinstimmung der Zuordnung (z. B. eine Spaltenzuordnung zu einem XML-Element desselben Namens) wählt die nicht komplexen Teilelemente aus, es sei denn, es wurde ein Muster auf Spaltenebene angegeben. Wenn das Teilelement komplex ist, weil es weitere Teilelemente enthält, wird die Spalte während des Abfrageprozesses auf NULL festgelegt. Attributwerte der Teilelemente werden dann ignoriert.

  • Wenn mehrere Teilelemente denselben Namen besitzen, wird der erste Knoten zurückgeliefert.

Siehe auch