Share via


Bewährte Methoden für XML

SQL Server 2005 bietet umfassende Unterstützung für die XML-Datenverarbeitung. XML-Werte können systemeigen in einer xml-Datentypspalte gespeichert werden, die gemäß einer Auflistung von XML-Schemas typisiert oder nicht typisiert werden kann. Sie können die XML-Spalte indizieren. Außerdem wird durch Verwenden von XQuery und XML DML eine differenzierte Datenbearbeitung unterstützt. XML DML ist eine Erweiterung zur Datenänderung.

SQL Server 2000 und SQLXML Web-Versionen bieten leistungsfähige Möglichkeiten zum Verwalten von XML-Daten. Diese Features sind auf die Zuordnung zwischen relationalen und XML-Daten ausgerichtet. XML-Sichten von relationalen Daten können mithilfe von AXDS (Annotated XSD) definiert werden, um eine XML-zentrierte Vorgehensweise bereitzustellen, die das Massenladen von Daten, das Abfragen sowie das Aktualisieren von XML-Daten ermöglicht. Transact-SQL-Erweiterungen ermöglichen eine SQL-zentrierte Vorgehensweise zum Zuordnen relationaler Abfrageergebnisse zu XML durch Verwenden von FOR XML und zum Generieren von relationalen Sichten aus XML-Daten mithilfe von OPENXML. Diese Unterstützung wurde in SQL Server 2005 erweitert. Gemeinsam mit der neu hinzugefügten systemeigenen XML-Unterstützung stellt SQL Server 2005 eine leistungsstarke Plattform zum Entwickeln umfassender Anwendungen zur Verwaltung halbstrukturierter und strukturierter Daten bereit.

Dieses Thema enthält Richtlinien für das Modellieren und Verwenden von XML-Daten in SQL Server 2005. Es ist in die folgenden Abschnitte unterteilt:

  • Datenmodellierung
    XML-Daten können in SQL Server 2005 auf verschiedene Weise gespeichert werden, indem der systemeigene xml-Datentyp verwendet und die XML-Daten in Tabellen aufgeteilt werden. Dieses Thema enthält Richtlinien, die Sie dabei unterstützen sollen, beim Modellieren Ihrer XML-Daten die geeigneten Entscheidungen zu treffen. Es behandelt auch das Indizieren von XML-Daten, die Eigenschaftenheraufstufung sowie die Typisierung von XML-Instanzen.
  • Verwendung
    In diesem Abschnitt werden verwendungsspezifische Themen behandelt, z. B. das Laden von XML-Daten in den Server und der Typrückschluss bei der Abfragekompilierung. In diesem Abschnitt werden auch eng miteinander verbundene Features genau erklärt, und es wird die richtige Verwendung dieser Features gezeigt. Die Verwendung wird anhand von Beispielen veranschaulicht.

Datenmodellierung

Dieser Abschnitt erklärt, warum Sie XML in SQL Server 2005 verwenden sollten. Der Abschnitt enthält auch Richtlinien zum Auswählen zwischen der systemeigenen XML-Speicherung und der XML-Sichttechnologie und enthält Vorschläge zur Datenmodellierung.

Relationales oder XML-Datenmodell

Wenn Ihre Daten sehr strukturiert sind und ein bekanntes Schema aufweisen, ist das relationale Modell möglicherweise zur Datenspeicherung am besten geeignet. SQL Server stellt die dazu erforderliche Funktionalität und die benötigten Tools bereit. Wenn Ihre Daten dagegen halbstrukturiert oder nicht strukturiert sind oder ihre Struktur unbekannt ist, müssen Sie das Modellieren dieser Daten in Erwägung ziehen.

XML ist eine gute Wahl, wenn Sie ein plattformunabhängiges Modell anstreben, um die Übertragbarkeit der Daten durch Verwendung von strukturellen und semantischen Markups sicherzustellen. XML ist darüber hinaus eine geeignete Option, wenn einige der folgenden Eigenschaften erfüllt sind:

  • Ihre Daten besitzen nur eine geringe Dichte, Sie kennen die Struktur der Daten nicht, oder die Struktur Ihrer Daten kann sich in Zukunft erheblich ändern.
  • Ihre Daten stellen keine Verweise zwischen Entitäten dar, sondern entsprechen einer Einkapselungshierarchie, die auch rekursiv sein kann.
  • Ihre Daten weisen eine inhärente Reihenfolge auf.
  • Sie wollen basierend auf der Struktur Ihrer Daten Abfragen in den Daten ausführen oder Teile der Daten aktualisieren.

Wenn keine dieser Bedingungen zutrifft, sollten Sie das relationale Datenmodell verwenden. Wenn die Daten z. B. im XML-Format vorliegen, die Anwendung die Datenbank jedoch ausschließlich zum Speichern und Abrufen der Daten verwendet, benötigen Sie lediglich eine [n]varchar(max)-Spalte. Das Speichern der Daten in einer XML-Spalte bietet weitere Vorteile. Beispielsweise kann mit dem Modul ermittelt werden, ob die Daten wohlgeformt oder gültig sind, und es werden auch differenzierte Abfragen und Aktualisierungen der XML-Daten unterstützt.

Gründe für das Speichern von XML-Daten in SQL Server 2005

Im Folgenden werden einige Gründe angeführt, die dafür sprechen, Ihre Daten nicht im Dateisystem zu verwalten, sondern die systemeigenen XML-Features in SQL Server 2005 zu verwenden.

  • Sie wollen Ihre XML-Daten auf effiziente und transaktive Weise freigeben, abfragen und ändern. Ein differenzierter Datenzugriff ist für Ihre Anwendung sehr wichtig. Sie wollen z. B. einige der Abschnitte innerhalb eines XML-Dokuments extrahieren, oder Sie wollen einen neuen Abschnitt einfügen, ohne Ihr gesamtes Dokument ersetzen zu müssen.
  • Sie verfügen über relationale Daten und XML-Daten und wollen innerhalb Ihrer Anwendung die Interoperabilität zwischen den relationalen Daten und den XML-Daten gewährleisten.
  • Sie benötigen die Sprachenunterstützung für Abfragen und Möglichkeiten zur Datenänderung für domänenübergreifende Anwendungen.
  • Sie wollen vom Server sicherstellen lassen, dass die Daten wohlgeformt sind, und Ihre Daten auch optional gemäß XML-Schemas überprüfen lassen.
  • Sie wünschen eine Indizierung von XML-Daten, um ein effizientes Verarbeiten von Abfragen und eine gute Skalierbarkeit zu ermöglichen, und wollen einen erstklassigen Abfrageoptimierer verwenden.
  • Sie wünschen den SOAP-, ADO.NET- und OLE DB-Zugriff auf XML-Daten.
  • Sie möchten Verwaltungsfunktionen für den Datenbankserver verwenden, um Ihre XML-Daten zu verwalten. Dazu gehören z. B. Sicherung, Wiederherstellung und Replikation der Daten.

Wenn keine dieser Bedingungen zutrifft, kann es besser sein, die Daten in einem Nicht-XML-Datentyp für große Objekte zu speichern, beispielsweise in [n]varchar(max) oder varbinary(max).

XML-Speicheroptionen

Für das Speichern von XML in SQL Server 2005 stehen die folgenden Optionen zur Verfügung:

  • Systemeigenes Speichern als xml-Datentyp
    Die Daten werden in einer internen Darstellung gespeichert, die den XML-Inhalt der Daten beibehält. Dazu gehören die Einkapselungshierarchie, die Dokumentreihenfolge sowie die Element- und Attributwerte. Insbesondere bleibt der InfoSet-Inhalt der XML-Daten erhalten. Weitere Informationen zu InfoSet finden Sie unter http://www.w3.org/TR/xml-infoset. Der InfoSet-Inhalt ist möglicherweise keine identische Kopie der Text-XML, weil die folgenden Informationen nicht erhalten bleiben: insignifikante Leerzeichen, Reihenfolge der Attribute, Namespace-Präfixe und XML-Deklaration.
    Für den typisierten xml -Datentyp, ein an XML-Schemas gebundener xml-Datentyp, werden durch das PSVI (Post-Schema Validation InfoSet) dem InfoSet Typinformationen hinzugefügt und in der internen Darstellung codiert. Das führt zu einer erheblichen Steigerung der Analysegeschwindigkeit. Weitere Informationen finden Sie in den Spezifikationen zum W3C XML-Schema unter http://www.w3.org/TR/xmlschema-1 und http://www.w3.org/TR/xmlschema-2.
  • Zuordnung zwischen XML- und relationaler Speicherung
    Durch Verwenden eines mit Anmerkungen versehenen Schemas (AXSD) wird der XML-Code in Spalten in einer oder mehreren Tabellen zerlegt. Damit bleibt die Genauigkeit der Daten auf der relationalen Ebene erhalten. Das führt dazu, dass die hierarchische Struktur erhalten bleibt, obwohl die Reihenfolge unter den Elementen ignoriert wird. Das Schema kann nicht rekursiv sein.
  • Speichern großer Objekte, [n]varchar(max) und varbinary(max)
    Eine identische Kopie der Daten wird gespeichert. Dies ist nützlich für Anwendungen mit einem besonderen Zweck wie z. B. zum Speichern juristischer Dokumente. Die meisten Anwendungen benötigen jedoch keine exakte Kopie, und es reicht der XML-Inhalt aus (InfoSet-Genauigkeit).

Im Allgemeinen müssen Sie eine Kombination aus diesen beiden Vorgehensweisen verwenden. Sie wollen z. B. die XML-Daten in einer xml-Datentypspalte speichern und Eigenschaften daraus in relationale Spalten heraufstufen. Oder Sie möchten die Zuordnungstechnologie verwenden, um nicht rekursive Teile in Nicht-XML-Spalten und ausschließlich die rekursiven Teile in xml -Datentypspalten zu speichern.

Auswählen der XML-Technologie

Die Auswahl der XML-Technologie – also systemeigene XML oder XML-Sicht – richtet sich im Allgemeinen nach den folgenden Faktoren:

  • Speicheroptionen
    Ihre XML-Daten können besser für die Speicherung großer Objekte geeignet sein (z. B. ein Produkthandbuch) oder kommen eher für die Speicherung in relationalen Spalten in Frage (z. B. ein in XML konvertierter Einzelposten). Mit jeder Speicheroption wird die Dokumentgenauigkeit in einem unterschiedlichen Ausmaß beibehalten.
  • Abfragemöglichkeiten
    Ausgehend vom Charakter Ihrer Abfragen und vom Ausmaß, in dem Sie Ihre XML-Daten abfragen, erscheint Ihnen möglicherweise eine Speicheroption geeigneter als eine andere. So wird mit den beiden Speicheroptionen die differenzierte Abfrage Ihrer XML-Daten, z. B. die Prädikatauswertung für XML-Knoten, in einem unterschiedlichen Ausmaß unterstützt.
  • Indizieren von XML-Daten
    Sie möchten möglicherweise die XML-Daten indizieren, um die Geschwindigkeit der XML-Abfrage zu erhöhen. Die Indexoptionen sind bei den beiden Speicheroptionen unterschiedlich, und Sie müssen die geeignete Auswahl treffen, um Ihre Arbeitsauslastung zu optimieren.
  • Möglichkeiten zur Datenänderung
    Bestimmte Arbeitsauslastungen erfordern ein differenziertes Ändern der XML-Daten. Das kann z. B. das Hinzufügen eines neuen Abschnitts zu einem Dokument einschließen, was bei anderen Arbeitsauslastungen wie z. B. Webinhalt nicht der Fall ist. Für Ihre Anwendung kann die Sprachenunterstützung bei der Datenänderung wichtig sein.
  • Unterstützung von Schemas
    Ihre XML-Daten können durch ein Schema beschrieben sein, bei dem es sich um ein XML-Schemadokument handeln kann oder auch nicht. Die Unterstützung für an Schemas gebundenen XML-Code richtet sich nach der ausgewählten XML-Technologie.

Die verschiedenen Auswahlmöglichkeiten sind auch mit unterschiedlichen Leistungsmerkmalen verbunden.

Systemeigene XML-Speicherung

Sie können die XML-Daten einer xml-Datentypspalte auf dem Server speichern. Dies ist eine geeignete Option, wenn folgende Aussagen zutreffen:

  • Sie benötigen eine einfache Methode zum Speichern Ihrer XML-Daten auf dem Server und wollen gleichzeitig die Dokumentreihenfolge und die Dokumentstruktur beibehalten.
  • Für Ihre XML-Daten kann ein Schema vorhanden sein, was aber nicht unbedingt der Fall sein muss.
  • Sie wollen Ihre XML-Daten abfragen und bearbeiten.
  • Sie wollen die XML-Daten indizieren, um die Abfrageverarbeitung zu beschleunigen.
  • Ihre Anwendung benötigt Systemkatalogsichten zum Verwalten Ihrer XML-Daten und XML-Schemas.

Die systemeigene XML-Speicherung ist nützlich, wenn Sie über XML-Dokumente mit vielfältigen Strukturen verfügen oder wenn Sie über XML-Dokumente verfügen, die verschiedenen oder komplexen Schemas entsprechen, sodass sie keinen relationalen Strukturen zugeordnet werden können.

Beispiel: Modellieren von XML-Daten mit dem xml-Datentyp

Stellen wir uns ein Produkthandbuch im XML-Format vor, das aus einem getrennten Kapitel für jedes Thema besteht und bei dem jedes Kapitel wiederum mehrere Abschnitte umfasst. Ein Abschnitt kann jeweils Unterabschnitte enthalten. Deshalb ist <section> (Abschnitt) ein rekursives Element. Produkthandbücher enthalten eine riesige Menge gemischter Inhalte, Diagramme und technischer Materialien; die Daten sind deshalb halbstrukturiert. Benutzer wollen möglicherweise eine Kontextsuche nach Themen von Interesse durchführen. So könnten sie z. B. nach dem Abschnitt zum Thema "gruppierter Index" innerhalb des Kapitels zum Thema "Indizieren" suchen und technische Mengen abfragen.

Ein geeignetes Speichermodell für die XML-Dokumente ist eine xml-Datentypspalte. Dabei bleibt der InfoSet-Inhalt Ihrer XML-Daten erhalten. Durch Indizieren der XML-Spalte wird die Abfrageleistung gesteigert.

Beispiel: Beibehalten exakter Kopien von XML-Daten

Nehmen wir zur Veranschaulichung an, dass Sie durch gesetzliche Bestimmungen dazu verpflichtet sind, exakte Textkopien Ihrer XML-Dokumente beizubehalten. Bei diesen Dokumenten könnte es sich z. B. um unterschriebene Dokumente, juristisch relevante Dokumente oder Unterlagen zu Börsengeschäften handeln. Möglicherweise möchten Sie dann die Dokumente in einer [n]varchar(max)-Spalte speichern.

Zu Abfragezwecken konvertieren Sie die Daten in den xml-Datentyp zur Laufzeit und führen daran XQuery-Abfragen aus. Die Konvertierung zur Laufzeit kann jedoch teuer sein, insbesondere wenn es sich um ein großes Dokument handelt. Wenn Sie häufig Abfragen ausführen, können Sie die Dokumente redundant in einer xml-Datentypspalte speichern und diese indizieren, während Sie genaue Dokumentkopien aus der [n]varchar(max)-Spalte zurückgeben.

Bei der XML-Spalte kann es sich um eine berechnete Spalte handeln, basierend auf der [n]varchar(max)-Spalte. Allerdings ist es nicht möglich, einen XML-Index für eine berechnete XML-Spalte zu erstellen, und auch für [n]varchar(max) - oder varbinary(max)-Spalten kann kein XML-Index erstellt werden.

XML-Sichttechnologie

Durch Definieren einer Zuordnung zwischen Ihren XML-Schemas und den Tabellen in einer Datenbank erstellen Sie eine "XML-Sicht" Ihrer dauerhaften Daten. Mithilfe von XML-Massenladen können die zugrunde liegenden Tabellen anhand der XML-Sicht aufgefüllt werden. Sie können die XML-Sicht mithilfe von XPath Version 1.0 abfragen; die Abfrage wird in SQL-Abfragen für die Tabellen übersetzt. In gleicher Weise werden auch Aktualisierungen an diese Tabellen weitergegeben.

Diese Technologie kann in folgenden Situationen nützlich sein:

  • Sie benötigen ein XML-zentriertes Programmierungsmodell mit Verwendung von XML-Sichten für Ihre vorhandenen relationalen Daten.
  • Sie verfügen über ein Schema (XSD, XDR) für Ihre XML-Daten, das eventuell von einem externen Partner stammt.
  • Die Reihenfolge spielt in Ihren Daten keine Rolle, oder Ihre Abfragetabelle ist nicht rekursiv, oder die maximale Rekursionstiefe ist bereits im Vorfeld bekannt.
  • Sie wollen die Daten über die XML-Sicht abfragen und bearbeiten, indem Sie XPath Version 1.0 verwenden.
  • Sie wollen einen Massenladevorgang für XML-Daten durchführen und diese mithilfe der XML-Sicht in die zugrunde liegenden Tabellen zerlegen.

Zu den Beispielen zählen relationale Daten, die als XML zum Datenaustausch und für Webdienste zugänglich gemacht werden, sowie XML-Daten mit festem Schema. Weitere Informationen finden Sie in der MSDN-Onlinebibliothek.

Beispiel: Modellieren von Daten mithilfe eines XML-Schemas mit Anmerkungen (AXSD)

Zur Veranschaulichung nehmen wir an, dass Sie über relationale Daten (z. B. zu Kunden, Bestellungen und Einzelposten) verfügen, die Sie als XML handhaben möchten. Definieren Sie eine XML-Sicht, indem Sie AXDS auf die relationalen Daten anwenden. Die XML-Sicht ermöglicht Ihnen, einen Massenladevorgang der XML-Daten in Ihre Tabellen durchzuführen und die relationalen Daten mithilfe der XML-Sicht abzufragen und zu aktualisieren. Dieses Modell ist nützlich, wenn Sie Daten, die XML-Markups enthalten, mit anderen Anwendungen austauschen müssen, während Ihre SQL-Anwendungen ununterbrochen weiterarbeiten.

Hybridmodell

Häufig ist für die Datenmodellierung eine Kombination aus relationalen Spalten und xml -Datentypspalten geeignet. Einige der Werte aus Ihren XML-Daten können in relationalen Spalten gespeichert werden, während der Rest oder der gesamte XML-Wert in einer XML-Spalte gespeichert wird. Das kann zu einer besseren Leistung führen, indem Sie über bessere Steuerungsmöglichkeiten für die Indizes, die für die relationalen Spalten erstellt wurden, und über bessere Sperrenmerkmale verfügen können.

Die Werte, die in relationalen Spalten gespeichert werden sollen, richten sich nach Ihrer Arbeitsauslastung. Wenn Sie z. B. alle XML-Werte auf der Basis des Pfadausdrucks /Customer/@CustId abrufen, kann das Heraufstufen des Wertes des CustId-Attributs in eine relationale Spalte und deren Indizierung zu einer Beschleunigung des Abfragevorgangs führen. Wenn Ihre XML-Daten andererseits umfangreich und nicht redundant in relationale Spalten zerlegt sind, können die Kosten für die Reassemblierung erheblich sein.

Wurde z. B. für stark strukturierte XML-Daten der Inhalt einer Tabelle in XML konvertiert, können Sie alle Werte relationalen Spalten zuordnen und möglicherweise die XML-Sichttechnologie verwenden.

Datenmodellierung mit dem xml-Datentyp

Dieser Abschnitt beschäftigt sich mit Themen der Datenmodellierung für die systemeigene XML-Speicherung. Dazu gehören das Indizieren von XML-Daten, das Heraufstufen von Eigenschaften und der typisierte xml-Datentyp.

Gleiche oder unterschiedliche Tabelle

Eine xml -Datentypspalte kann entweder in einer Tabelle erstellt werden, die noch andere relationale Spalten enthält, oder in einer getrennten Tabelle mit einer Fremdschlüsselbeziehung zu einer Haupttabelle.

Erstellen Sie eine xml -Datentypspalte in derselben Tabelle, wenn eine der folgenden Bedingungen zutrifft:

  • Ihre Anwendung führt einen Datenabruf für die XML-Spalte durch und benötigt keinen XML-Index für die XML-Spalte.
  • Sie möchten einen XML-Index für die xml-Datentypspalte erstellen, und der Primärschlüssel der Haupttabelle ist derselbe wie ihr Gruppierungsschlüssel. Weitere Informationen finden Sie unter "Indizieren einer xml-Datentypspalte".

Erstellen Sie die xml-Datentypspalte in einer getrennten Tabelle, wenn die folgenden Bedingungen zutreffen:

  • Sie möchten einen XML-Index für die xml-Datentypspalte erstellen, der Primärschlüssel der Haupttabelle unterscheidet sich jedoch von ihrem Gruppierungsschlüssel, oder die Haupttabelle besitzt keinen Primärschlüssel, oder die Haupttabelle ist ein Heap (kein Gruppierungsschlüssel). Das kann der Fall sein, wenn die Haupttabelle bereits vorhanden ist.
  • Sie wollen vermeiden, dass Tabellenscans verlangsamt werden, weil die XML-Spalte in der Tabelle vorhanden ist. Dies beansprucht Speicherplatz, unabhängig davon, ob die Speicherung innerhalb oder außerhalb der Zeile erfolgt.

Granularität von XML-Daten

Die Granularität der in einer XML-Spalte gespeicherten XML-Daten ist für Sperrungen sehr wichtig und ist – in einem geringeren Ausmaß – auch für Aktualisierungen wichtig. SQL Server verwendet denselben Sperrmechanismus sowohl für XML- als auch für Nicht-XML-Daten. Deshalb führt eine Sperrung auf Zeilenebene dazu, dass alle XML-Instanzen in der Zeile gesperrt werden. Bei hoher Granularität führt die Sperrung großer XML-Instanzen für Aktualisierungen in einem Szenario mit mehreren Benutzern zur Verringerung des Datendurchsatzes. Andererseits geht bei starker Dekomposition die Objekteinkapselung verloren, und die Kosten für die Reassemblierung steigen.

Um einen guten Entwurf zu erzielen, muss ein Kompromiss aus den Anforderungen der Datenmodellierung und den Sperrungs- und Aktualisierungsmerkmalen gefunden werden. In SQL Server 2005 ist jedoch die Größe der tatsächlich gespeicherten XML-Instanzen nicht von so entscheidender Bedeutung.

Beispielsweise wird für Aktualisierungen einer XML-Instanz die neue Unterstützung für teilweise BLOB- (Binary Large Object) und teilweise Indexaktualisierung genutzt, bei der die vorhandene gespeicherte XML-Instanz mit ihrer aktualisierten Version verglichen wird. Bei der BLOB-Aktualisierung wird ein differenzieller Vergleich zwischen den beiden XML-Instanzen durchgeführt, und es werden nur die Differenzen aktualisiert. Teilweise Indexaktualisierungen nehmen im XML-Index nur Änderungen an solchen Zeilen vor, die geändert werden müssen.

Nicht typisierter, typisierter und eingeschränkter xml-Datentyp

Der von SQL Server 2005 verwendete xml-Datentyp implementiert den xml-Standarddatentyp gemäß ISO SQL-2003. Deshalb ermöglicht er das Speichern sowohl von wohlgeformten XML-Dokumenten der Version 1.0 als auch von so genannten XML-Inhaltsfragmenten mit Textknoten und einer beliebigen Anzahl von Elementen auf der obersten Ebene in einer nicht typisierten XML-Spalte. Das System überprüft, ob die Daten wohlgeformt sind – wobei es nicht erforderlich ist, dass die Spalte an XML-Schemas gebunden ist – und weist alle Daten zurück, die in diesem erweiterten Sinne nicht wohlgeformt sind. Dies gilt auch für nicht typisierte XML-Variablen und -Parameter.

Wenn Sie über XML-Schemas zum Beschreiben Ihrer XML-Daten verfügen, können Sie die Schemas der XML-Spalte zuordnen, um typisiertes XML zu erhalten. Die XML-Schemas werden verwendet, um die Gültigkeit der Daten zu überprüfen, um präzisere Typüberprüfungen während der Kompilierung von Abfrage- und Datenänderungsanweisungen als bei nicht typisiertem XML durchzuführen und um die Speicherungs- und Abfrageverarbeitung zu optimieren.

Verwenden Sie den nicht typisierten xml-Datentyp in den folgenden Situationen:

  • Sie verfügen über kein Schema für Ihre XML-Daten.
  • Sie verfügen zwar über Schemas, wollen jedoch die Gültigkeit der Daten nicht durch den Server überprüfen lassen. Dies ist manchmal der Fall, wenn eine Anwendung eine clientseitige Gültigkeitsprüfung vor dem Speichern der Daten auf dem Server durchführt oder gemäß dem Schema ungültige XML-Daten temporär speichert oder Schemakomponenten verwendet, die vom Server nicht unterstützt werden (z. B. key/keyref).

Verwenden Sie den typisierten xml -Datentyp in den folgenden Situationen:

  • Sie verfügen über Schemas für Ihre XML-Daten und wollen, dass der Server anhand der XML-Schemas die Gültigkeit Ihrer XML-Daten überprüft.
  • Sie möchten Speicherungs- und Abfrageoptimierungen nutzen, die auf den Typinformationen basieren.
  • Sie möchten beim Kompilieren Ihrer Abfragen einen größeren Nutzen aus den Typinformationen ziehen.

Typisierte XML-Spalten, -Parameter und -Variablen können XML-Dokumente oder -Inhalte speichern. Allerdings müssen Sie zum Zeitpunkt der Deklaration durch ein Flag angeben, ob Sie ein Dokument oder einen Inhalt speichern. Außerdem müssen Sie die Auflistung der XML-Schemas bereitstellen. Geben Sie DOCUMENT an, wenn jede XML-Instanz genau ein Element auf der obersten Ebene aufweist. Verwenden Sie ansonsten CONTENT. Der Abfragecompiler verwendet das DOCUMENT-Flag bei den Typüberprüfungen während der Abfragekompilierung, um Singleton-Elemente auf der obersten Ebene abzuleiten.

Zusätzlich zur Typisierung einer XML-Spalte können Sie relationale (Spalte oder Zeile) Einschränkungen für typisierte oder nicht typisierte xml-Datentypspalten verwenden. Verwenden Sie Einschränkungen in den folgenden Situationen:

  • Ihre Geschäftsrichtlinien können nicht in XML-Schemas ausgedrückt werden. Beispielsweise muss sich die Lieferadresse eines Blumenladens in einem Umkreis von 50 Kilometern zum Ladenstandort befinden. Dies kann in Form einer Einschränkung für die XML-Spalte formuliert werden. Die Einschränkung kann xml-Datentypmethoden einbeziehen.
  • Ihre Einschränkung bezieht andere XML- oder Nicht-XML-Spalten in der Tabelle ein. Ein Beispiel wäre es, wenn die Übereinstimmung der ID eines in einer XML-Instanz gefundenen Kunden (/Customer/@CustId) mit dem Wert in einer relationalen CustomerID-Spalte erzwungen werden soll.

Dokumenttypdefinition (DTD)

Die Spalten, Variablen und Parameter des xml-Datentyps können mithilfe eines XML-Schemas typisiert werden, jedoch nicht mithilfe von DTD. Allerdings kann Inline-DTD sowohl für nicht typisiertes als auch für typisiertes XML verwendet werden, um Standardwerte bereitzustellen und um Entitätsverweise durch ihre erweiterte Form zu ersetzen.

Mithilfe von Drittanbieter-Tools können Sie DTDs in XML-Schemadokumente konvertieren und die XML-Schemas in die Datenbank laden.

Indizieren einer xml-Datentypspalte

XML-Indizes können für xml-Datentypspalten erstellt werden. Dabei werden alle Tags, Werte und Pfade für die XML-Instanzen in der Spalte indiziert. Die Indizierung verbessert die Abfrageleistung. Ihre Anwendung kann in folgenden Situationen von einem XML-Index profitieren:

  • In Ihren Arbeitsauslastungen sind Abfragen von XML-Spalten üblich. Die Wartungskosten für den XML-Index während der Datenänderung müssen berücksichtigt werden.
  • Ihre XML-Werte sind relativ groß, und die abgerufenen Teile sind relativ klein. Mit dem Erstellen eines Indexes wird vermieden, dass zur Laufzeit die gesamten Daten analysiert werden müssen; davon profitieren Indexsuchen zur effizienten Abfrageverarbeitung.

Der erste Index für eine XML-Spalte ist der primäre XML-Index. Durch seine Verwendung können drei Typen von sekundären XML-Indizes für die XML-Spalte erstellt werden, um allgemeine Abfrageklassen zu beschleunigen. Dies wird im folgenden Abschnitt beschrieben.

Primärer XML-Index

Dieser Index indiziert alle Tags, Werte und Pfade innerhalb der XML-Instanzen in einer XML-Spalte. Die Basistabelle – also die Tabelle, in der die XML-Spalte vorkommt – muss über einen gruppierten Index für den Primärschlüssel der Tabelle verfügen. Der Primärschlüssel wird verwendet, um die Indexzeilen in Beziehung zu den Zeilen in der Basistabelle zu setzen. Vollständige XML-Instanzen werden aus den XML-Spalten abgerufen, z. B. SELECT *. Abfragen verwenden den primären XML-Index und geben Skalarwerte oder XML-Teilbäume zurück, indem der Index selbst verwendet wird.

Beispiel: Erstellen eines primären XML-Indexes

In den meisten Beispielen wird Tabelle T (pk INT PRIMARY KEY, xCol XML) mit einer nicht typisierten XML-Spalte verwendet. Diese können auf einfache Weise zu typisiertem XML erweitert werden. Weitere Informationen zum Verwenden von typisiertem XML finden Sie unter XML-Datentyp. Aus Gründen der Vereinfachung werden die Abfragen für XML-Dateninstanzen beschrieben, wie das im folgenden Beispiel gezeigt wird:

<book genre="security" publicationdate="2002" ISBN="0-7356-1588-2">
   <title>Writing Secure Code</title>
   <author>
      <first-name>Michael</first-name>
      <last-name>Howard</last-name>
   </author>
   <author>
      <first-name>David</first-name>
      <last-name>LeBlanc</last-name>
   </author>
   <price>39.99</price>
</book>

Die folgende Anweisung erstellt einen XML-Index mit der Bezeichnung idx_xCol für die XML-Spalte xCol der Tabelle T:

CREATE PRIMARY XML INDEX idx_xCol on T (xCol)

Sekundäre XML-Indizes

Nachdem Sie den primären XML-Index erstellt haben, können Sie bei Bedarf sekundäre XML-Indizes erstellen, um unterschiedliche Abfrageklassen innerhalb Ihrer Arbeitsauslastung zu beschleunigen. Von den drei möglichen Typen sekundärer XML-Indizes – d. h. PATH, PROPERTY und VALUE – profitieren pfadbasierte Abfragen, Szenarien zum Verwalten benutzerdefinierter Eigenschaften bzw. wertebasierte Abfragen. Der PATH-Index erstellt einen B+-Baum für das (path, value)-Paar jedes XML-Knotens in der Dokumentreihenfolge für alle XML-Instanzen in der Spalte. Der PROPERTY-Index erstellt einen B+-Baum, der für das (PK, path, value)-Paar innerhalb jeder XML-Instanz gruppiert ist, wobei PK der Primärschlüssel der Basistabelle ist. Und schließlich erstellt der VALUE-Index einen B+-Baum für das (value, path)-Paar jedes Knotens in der Dokumentreihenfolge für alle XML-Instanzen in der XML-Spalte.

Es folgen einige Richtlinien zum Erstellen von einem oder mehrerer dieser Indizes:

  • Wenn bei Ihrer Arbeitsauslastung im erheblichen Ausmaß Pfadausdrücke für XML-Spalten verwendet werden, führt der sekundäre XML-Index des Typs PATH wahrscheinlich zu einer Beschleunigung Ihrer Arbeitsauslastung. Der häufigste Fall ist das Verwenden der exist()-Methode für XML-Spalten in der WHERE-Klausel von Transact-SQL.
  • Wenn bei Ihrer Arbeitsauslastung mehrere Werte aus einzelnen XML-Instanzen mithilfe von Pfadausdrucken abgerufen werden, kann das Gruppieren der Pfade innerhalb jeder XML-Instanz im PROPERTY-Index nützlich sein. Diese Situation tritt üblicherweise in einem Eigenschaftsbehälterszenario auf, wenn die Eigenschaften eines Objekts abgerufen werden und dessen Primärschlüsselwert bekannt ist.
  • Wenn bei Ihrer Arbeitsauslastung das Abfragen von Werten innerhalb von XML-Instanzen vorkommt, ohne dass dabei die Element- oder Attributnamen bekannt sind, die diese Werte enthalten, können Sie den VALUE-Index erstellen. Diese Situation kommt üblicherweise beim Durchsuchen von descendant-Achsen vor, z. B. bei //author[last-name="Howard"], wo die <author>-Elemente in jeder beliebigen Ebene der Hierarchie auftreten können. Sie kommt auch bei Abfragen mit Platzhaltern vor, z. B. bei /book [@* = "novel"], wobei die Abfrage nach <book>-Elementen sucht, die über irgendein Attribut verfügen, das den Wert "novel" aufweist.
Beispiel: Pfadbasierte Suche

Zur Veranschaulichung nehmen wir an, die folgende Abfrage ist in Ihrer Arbeitsauslastung üblich:

SELECT pk, xCol
FROM   T
WHERE  xCol.exist ('/book/@genre[.="novel"]') = 1

Der Pfadausdruck /book/@genre und der Wert "novel" entsprechen dabei den Schlüsselfeldern des PATH-Indexes. Deshalb wäre für diese Arbeitsauslastung ein sekundärer XML-Index des PATH-Typs nützlich:

CREATE XML INDEX idx_xCol_Path on T (xCol)
   USING XML INDEX idx_xCol FOR PATH
Beispiel: Abrufen der Eigenschaften eines Objekts

Nehmen wir die folgende Abfrage an, die aus jeder Zeile in Tabelle T die Eigenschaften "genre", "title" und "ISBN" eines Buchs abruft.

SELECT xCol.value ('(/book/@genre)[1]', 'varchar(50)'),
    xCol.value ('(/book/title/text())[1]', 'varchar(50)'),
    xCol.value ('(/book/@ISBN)[1]', 'varchar(50)')
FROM    T

Der PROPERTY-Index ist in diesem Fall hilfreich. Er wird folgendermaßen erstellt:

CREATE XML INDEX idx_xCol_Property on T (xCol)
   USING XML INDEX idx_xCol FOR PROPERTY
Beispiel: Wertebasierte Abfrage

In der folgenden Abfrage gibt die descendant-or-self-Achse (//) einen Teilpfad an, sodass die auf dem Wert von "ISBN" basierende Suche von der Verwendung des VALUE-Indexes profitiert:

SELECT xCol
FROM    T
WHERE    xCol.exist ('//book/@ISBN[. = "0-7356-1588-2"]') = 1

Der VALE-Index wird folgendermaßen erstellt:

CREATE XML INDEX idx_xCol_Value on T (xCol)
   USING XML INDEX idx_xCol FOR VALUE

Volltextindex für eine XML-Spalte

Sie können einen Volltextindex für XML-Spalten erstellen, bei dem zwar der Inhalt der XML-Werte indiziert wird, jedoch die XML-Markups ignoriert werden. Attributwerte werden nicht vom Volltextindex erfasst, weil sie als Bestandteil der Markups angesehen werden, und Elementtags werden als Tokengrenzen verwendet. Gegebenenfalls können Sie die Volltextsuche mit dem XML-Index auf folgende Weise kombinieren:

  • Filtern Sie zuerst die XML-Werte von Interesse mithilfe der SQL-Volltextsuche.
  • Fragen Sie als Nächstes solche XML-Werte ab, die den XML-Index für die XML-Spalte verwenden.
Beispiel: Kombinieren der Volltextsuche mit einer XML-Abfrage

Nachdem der Volltextindex für die XML-Spalte erstellt wurde, überprüft die folgende Abfrage, ob ein XML-Wert das Wort "custom" im Titel eines Buchs enthält:

SELECT * 
FROM   T 
WHERE  CONTAINS(xCol,'custom') 
AND    xCol.exist('/book/title/text()[contains(.,"custom")]') =1

Die contains()-Methode verwendet den Volltextindex, um die XML-Werte, die das Wort "custom" irgendwo im Dokument enthalten, zu einer Teilmenge zusammenzufassen. Die exist()-Klausel stellt sicher, dass das Wort "custom" im Titel eines Buchs vorkommt.

Eine Volltextsuche mit der contains()-Klausel und XQuery mithilfe der contains()-Klausel weisen unterschiedliche Semantiken auf. Das Letztere ist eine Teilzeichenfolgenübereinstimmung, und das Erstere ist eine Tokenübereinstimmung mithilfe der Wortformgenerierung. Wenn die Suche nach der Zeichenfolge erfolgt, die "run" im Titel enthält, gilt neben "run" auch "runs" und "running" als Übereinstimmung, weil sowohl die Volltextklausel contains() als auch die XQuery-Klausel contains() erfüllt ist. Allerdings ergibt die Abfrage keine Übereinstimmung des Wortes "customizable" im Titel, weil die Volltextklausel contains() nicht erfüllt ist, obwohl die XQuery-Klausel contains() erfüllt ist. Im Allgemeinen sollte für eine reine Teilzeichenfolgenübereinstimmung die Volltextklausel contains() entfernt werden.

Außerdem verwendet die Volltextsuche die Wortformgenerierung, während XQuery contains() eine Literalübereinstimmung ist. Dieser Unterschied wird im folgenden Beispiel veranschaulicht.

Beispiel: Volltextsuche für XML-Werte mit Wortformgenerierung

Die XQuery contains()-Überprüfung, die im vorherigen Beispiel durchgeführt wurde, kann im Allgemeinen nicht eliminiert werden. Angenommen, die folgende Abfrage wird ausgeführt:

SELECT * 
FROM   T 
WHERE  CONTAINS(xCol,'run') 

Das Wort "ran" im Dokument stimmt wegen der Verwendung der Wortformgenerierung mit der Suchbedingung überein. Außerdem wird der Suchkontext nicht mithilfe von XQuery überprüft.

Wenn XML in relationale Spalten zerlegt wird, indem volltextindizierte AXSD verwendet wird, führen XPath-Abfragen, die für die XML-Sicht ausgeführt werden, keine Volltextsuche der zugrunde liegenden Tabellen durch.

Heraufstufen von Eigenschaften

Wenn Abfragen in erster Linie nur für eine geringe Anzahl von Element- und Attributwerten ausgeführt werden, kann es sinnvoll sein, diese Mengen in relationale Spalten heraufzustufen. Dies ist nützlich, wenn Abfragen für einen kleinen Teil der XML-Daten ausgegeben werden, während die gesamte XML-Instanz abgerufen wird. Das Erstellen eines XML-Indexes für die XML-Spalte ist nicht erforderlich. Stattdessen kann die heraufgestufte Spalte indiziert werden. Um die heraufgestufte Spalte zu verwenden, müssen Abfragen geschrieben werden. Das heißt, der Abfrageoptimierer richtet die Abfragen für die XML-Spalte nicht erneut an die heraufgestufte Spalte aus.

Die heraufgestufte Spalte kann entweder eine berechnete Spalte in derselben Tabelle oder eine getrennte, benutzerverwaltete Spalte in einer Tabelle sein. Dies ist ausreichend, wenn Singleton-Werte aus jeder XML-Instanz heraufgestuft werden. Allerdings müssen Sie für mehrwertige Eigenschaften eine getrennte Tabelle für die Eigenschaft erstellen, was im folgenden Abschnitt beschrieben wird.

Berechnete Spalte auf der Basis des xml-Datentyps

Eine berechnete Spalte kann mithilfe einer benutzerdefinierten Funktion erstellt werden, die xml-Datentypmethoden aufruft. Der Typ der berechneten Spalte kann jeder SQL-Typ sein, einschließlich XML. Dies wird im folgenden Beispiel veranschaulicht.

Beispiel: Berechnete Spalte auf der Basis der xml-Datentypmethode

Erstellen Sie die benutzerdefinierte Funktion für die ISBN-Nummer eines Buchs:

CREATE FUNCTION udf_get_book_ISBN (@xData xml)
RETURNS varchar(20)
BEGIN
   DECLARE @ISBN   varchar(20)
   SELECT @ISBN = @xData.value('/book[1]/@ISBN', 'varchar(20)')
   RETURN @ISBN 
END

Fügen Sie der Tabelle eine berechnete Spalte für die ISBN hinzu:

ALTER TABLE      T
ADD   ISBN AS dbo.udf_get_book_ISBN(xCol)

Die berechnete Spalte kann auf gewöhnliche Weise indiziert werden.

Beispiel: Abfragen für eine berechnete Spalte auf der Basis der xml-Datentypmethoden

So erhalten Sie das <book>-Element, dessen ISBN 0-7356-1588-2 ist:

SELECT xCol
FROM   T
WHERE  xCol.exist('/book/@ISBN[. = "0-7356-1588-2"]') = 1

Die Abfrage für die XML-Spalte kann so umgeschrieben werden, dass sie die berechnete Spalte verwendet:

SELECT xCol
FROM   T
WHERE  ISBN = '0-7356-1588-2'

Sie können eine benutzerdefinierte Funktion erstellen, die den xml-Datentyp zurückgibt, und eine berechnete Spalte mithilfe dieser benutzerdefinierten Funktion. Allerdings können Sie keinen XML-Index für die berechnete XML-Spalte erstellen.

Erstellen von Eigenschaftentabellen

Wenn Sie einige der mehrwertigen Eigenschaften aus Ihren XML-Daten in eine oder mehrere Tabellen heraufstufen möchten, erstellen Sie Indizes für diese Tabellen und richten Sie Ihre Abfrage erneut so aus, dass sie diese Indizes verwenden. Ein typisches Szenario hierfür ist eine Situation, in der eine kleine Anzahl von Eigenschaften den Großteil Ihrer Abfragearbeitsauslastung abdeckt. Sie können folgendermaßen vorgehen:

  • Erstellen Sie eine oder mehrere Tabellen, die die mehrwertigen Eigenschaften aufnehmen. Sie könnten praktischerweise so vorgehen, dass Sie eine Eigenschaft pro Tabelle speichern und den Primärschlüssel der Basistabelle in den Eigenschaftentabellen speichern, um eine Rückwärtsverknüpfung mit der Basistabelle zu erreichen.
  • Wenn Sie die relative Reihenfolge der Eigenschaften beibehalten möchten, müssen Sie eine getrennte Spalte für die relative Reihenfolge einführen.
  • Erstellen Sie Trigger für die XML-Spalte, um die Eigenschaftentabellen zu verwalten. Führen Sie innerhalb der Trigger einen der folgenden Schritte aus:
    • Verwenden Sie xml-Datentypmethoden, z. B. nodes() und value(), um Zeilen der Eigenschaftentabellen einzufügen oder zu löschen.
    • Erstellen Sie Streaming-Tabellenwertfunktionen in CLR (Common Language Runtime), um Zeilen der Eigenschaftentabellen einzufügen oder zu löschen.
    • Schreiben Sie Abfragen für den SQL-Zugriff auf die Eigenschaftentabellen und für den XML-Zugriff auf die XML-Spalte in der Basistabelle, wodurch Verknüpfungen zwischen den Tabellen mithilfe ihres Primärschlüssels erstellt werden.
Beispiel: Erstellen einer Eigenschaftentabelle

Angenommen, Sie wollen den ersten Vornamen des Autors heraufstufen. Bücher weisen einen oder mehrere Autoren auf, sodass der Vorname eine mehrwertige Eigenschaft ist. Jeder Vorname ist in einer getrennten Zeile einer Eigenschaftentabelle gespeichert. Der Primärschlüssel der Basistabelle wird in die Eigenschaftentabelle dupliziert, um eine Rückwärtsverknüpfung zu erstellen.

create table tblPropAuthor (propPK int, propAuthor varchar(max))
Beispiel: Erstellen einer benutzerdefinierten Funktion zum Generieren eines Rowsets aus einer XML-Instanz

Die folgende Tabellenwertfunktion (udf_XML2Table) akzeptiert einen Primärschlüsselwert und eine XML-Instanz. Sie ruft den Vornamen aller Autoren aus den <book>-Elementen ab und gibt ein Rowset mit Paaren aus Primärschlüssel und Vorname zurück.

create function udf_XML2Table (@pk int, @xCol xml)
returns @ret_Table table (propPK int, propAuthor varchar(max))
with schemabinding
as
begin
      insert into @ret_Table 
      select @pk, nref.value('.', 'varchar(max)')
      from   @xCol.nodes('/book/author/first-name') R(nref)
      return
end
Beispiel: Erstellen von Triggern zum Auffüllen einer Eigenschaftentabelle

Der insert-Trigger bewirkt das Einfügen von Zeilen in die Eigenschaftentabelle:

create trigger trg_docs_INS on T for insert
as
      declare @wantedXML xml
      declare @FK int
      select @wantedXML = xCol from inserted
      select @FK = PK from inserted

   insert into tblPropAuthor
   select * from dbo.udf_XML2Table(@FK, @wantedXML)

Der delete-Trigger löscht die Zeilen aus der Eigenschaftentabelle und richtet sich dabei nach dem Primärschlüsselwert der gelöschten Zeilen.

create trigger trg_docs_DEL on T for delete
as
   declare @FK int
   select @FK = PK from deleted
   delete tblPropAuthor where propPK = @FK

Der update-Trigger löscht die vorhandenen Zeilen in der Eigenschaftentabelle entsprechend der aktualisierten XML-Instanz und fügt neue Zeilen in die Eigenschaftentabelle ein:

create trigger trg_docs_UPD
on T
for update
as
if update(xCol) or update(pk)
begin
      declare @FK int
      declare @wantedXML xml
      select @FK = PK from deleted
      delete tblPropAuthor where propPK = @FK

   select @wantedXML = xCol from inserted
   select @FK = pk from inserted

   insert into tblPropAuthor 
      select * from dbo.udf_XML2Table(@FK, @wantedXML)
end
Beispiel: Suchen nach XML-Instanzen, deren Autoren den Vornamen "David" haben

Die Abfrage kann für die XML-Spalte geformt werden. Alternativ kann sie die Eigenschaftentabelle nach dem Vornamen "David" durchsuchen und eine Rückwärtsverknüpfung mit der Basistabelle ausführen, um die XML-Instanz zurückzugeben: Beispiel:

SELECT xCol 
FROM     T JOIN tblPropAuthor ON T.pk = tblPropAuthor.propPK
WHERE    tblPropAuthor.propAuthor = 'David'
Beispiel: Projektmappe mit Verwendung der Streaming-Tabellenwertfunktion in CLR

Diese Projektmappe umfasst die folgenden Schritte:

  1. Definieren Sie eine CLR-Klasse (SqlReaderBase), die ISqlReader implementiert und eine Tabellenwert-Streaming-Ausgabe generiert, indem ein Pfadausdruck auf eine XML-Instanz angewendet wird.
  2. Erstellen Sie ein Assembly und eine benutzerdefinierte Transact-SQL-Funktion, um die CLR-Klasse zu starten.
  3. Definieren Sie die insert-, update- und delete-Trigger, indem Sie die benutzerdefinierte Funktion zum Verwalten einer Eigenschaftentabelle verwenden.

Dazu erstellen Sie zuerst die Streaming-CLR-Funktion. Der xml-Datentyp wird als eine verwaltete SqlXml-Klasse in ADO.NET verfügbar gemacht und unterstützt die CreateReader()-Methode, die einen XmlReader zurückgibt.

ms187508.note(de-de,SQL.90).gifHinweis:
Der Beispielcode in diesem Abschnitt verwendet XPathDocument und XPathNavigator. Diese zwingen Sie, alle XML-Dokumente in den Arbeitsspeicher zu laden. Wenn Sie ähnlichen Code in Ihrer Anwendung verwenden, um mehrere große XML-Dokumente zu verarbeiten, ist dieser Code nicht skalierbar. Halten Sie stattdessen die Zuweisung von Arbeitsspeicher gering, und verwenden Sie wenn möglich Streaming-Schnittstellen. Weitere Informationen zur Leistung finden Sie unter Architecture of CLR Integration.
public class c_streaming_xml_tvf {
   public static ISqlReader streaming_xml_tvf 
(SqlXml xmlDoc, string pathExpression) {
      return (new TestSqlReaderBase (xmlDoc, pathExpression));
   }
}

// Class that implements ISqlReader
public class TestSqlReaderBase : ISqlReader {
XPathNodeIterator m_iterator;         
   public SqlChars FirstName;
// Metadata for current resultset
private SqlMetaData[] m_rgSqlMetaData;      

   public TestSqlReaderBase (SqlXml xmlDoc, string pathExpression) {   
      // Variables for XPath navigation
      XPathDocument xDoc;
      XPathNavigator xNav;
      XPathExpression xPath;
   
      // Set sql metadata
      m_rgSqlMetaData = new SqlMetaData[1];
      m_rgSqlMetaData[0] = new SqlMetaData ("FirstName",  
SqlDbType.NVarChar,50);   
   
      //Set up the Navigator
      if (!xmlDoc.IsNull)
          xDoc = new XPathDocument (xmlDoc.CreateReader());
      else
          xDoc = new XPathDocument ();
      xNav = xDoc.CreateNavigator();
      xPath = xNav.Compile (pathExpression);
      m_iterator = xNav.Select(xPath);
   }
   public bool Read() {
      bool moreRows = true;
      if (moreRows = m_iterator.MoveNext())
         FirstName = new SqlChars (m_iterator.Current.Value);
      return moreRows;
   }
}

Erstellen Sie als Nächstes eine Assembly und eine benutzerdefinierte Transact-SQL-Funktion – SQL_streaming_xml_tvf (nicht dargestellt) –, die der CLR-Funktion streaming_xml_tvf entspricht. Die benutzerdefinierte Funktion wird zum Definieren der Tabellenwertfunktion CLR_udf_XML2Table verwendet, mit der das Rowset generiert wird:

create function CLR_udf_XML2Table (@pk int, @xCol xml)
returns @ret_Table table (FK int, FirstName varchar(max))
with schemabinding
as
begin
      insert into @ret_Table 
   select @pk, FirstName 
   FROM   SQL_streaming_xml_tvf (@xCol, '/book/author/first-name')
      return
end

Definieren Sie schließlich die Trigger wie im Beispiel "Erstellen von Triggern zum Auffüllen einer Eigenschaftentabelle", ersetzen Sie dabei jedoch udf_XML2Table durch die CLR_udf_XML2Table-Funktion. Der insert-Trigger ist im folgenden Beispiel dargestellt:

create trigger CLR_trg_docs_INS on T for insert
as
   declare @wantedXML xml
   declare @FK int
   select @wantedXML = xCol from inserted
   select @FK = PK from inserted

   insert into tblPropAuthor
      select *
   from    dbo.CLR_udf_XML2Table(@FK, @wantedXML)

Der delete-Trigger ist identisch mit der Nicht-CLR-Version. Dagegen ist beim update-Trigger lediglich die Funktion udf_XML2Table() durch CLR_udf_XML2Table() ersetzt.

XML-Schemaauflistungen

Eine XML-Schemaauflistung ist eine Metadatenentität, deren Bereich durch ein relationales Schema bestimmt wird. Sie enthält eine oder mehrere XML-Schemas, die entweder verknüpft (z. B. durch <xs:import>) oder nicht verknüpft sein können. Die einzelnen XML-Schemas innerhalb einer XML-Schemaauflistung werden durch ihren Zielnamespace identifiziert.

Eine XML-Schemaauflistung wird erstellt, indem die CREATE XML SCHEMA COLLECTION (Transact-SQL)-Syntax verwendet und ein oder mehrere XML-Schemas bereitgestellt werden. Mehrere XML-Schemakomponenten können einem vorhandenen XML-Schema hinzugefügt werden, und mehrere Schemas können einer XML-Schemaauflistung hinzugefügt werden, indem die ALTER XML SCHEMA COLLECTION (Transact-SQL)-Syntax verwendet wird. XML-Schemaauflistungen können wie alle SQL-Objekte gesichert werden, indem das Sicherheitsmodell in SQL Server 2005 verwendet wird.

Mehrfach typisierte Spalten

Eine XML-Schemaauflistung C typisiert eine XML-Spalte (xCol) entsprechend mehreren XML-Schemas. Außerdem wird durch die DOCUMENT- und CONTENT-Flags angegeben, ob in der Spalte xCol XML-Bäume oder Fragmente gespeichert werden können.

Für DOCUMENT gibt jede XML-Instanz den Zielnamespace ihres Elements auf der obersten Ebene in der Instanz an, das typisiert und entsprechend überprüft wird. Dagegen kann für CONTENT jedes Element auf der obersten Ebene jeden der Zielnamespaces in C angeben. Die XML-Instanz wird entsprechend allen in einer Instanz auftretenden Zielnamespaces überprüft und typisiert.

Schemaauswertung

Die XML-Schemaauflistung wird zum Typisieren von XML-Spalten, -Variablen und -Parametern verwendet. Sie stellt einen Mechanismus zur XML-Schemaauswertung bereit. Angenommen, Sie fügen einer XML-Schemaauflistung C ein XML-Schema mit dem Zielnamespace BOOK-V1 hinzu. Die mithilfe von C typisierte XML-Spalte xCol kann XML-Daten speichern, die dem BOOK-V1-Schema entsprechen.

Nehmen wir nun an, dass durch eine Anwendung das XML-Schema durch neue Schemakomponenten erweitert werden soll, z. B. durch Definitionen mit komplexem Typ und Deklarationen von Elementen auf der obersten Ebene. Diese neuen Schemakomponenten können dem BOOK-V1-Schema hinzugefügt werden, wozu keine erneute Überprüfung der vorhandenen XML-Daten in der Spalte xCol erforderlich ist.

Angenommen, die Anwendung soll später eine neue Version des XML-Schemas bereitstellen und wählt dazu den Zielnamespace BOOK-V2 aus. Dieses XML-Schema kann C hinzugefügt werden. Die XML-Spalte kann Instanzen sowohl von BOOK-V1 und von BOOK-V2 speichern und Abfragen und Datenänderungen für XML-Instanzen ausführen, die diesen Namespaces entsprechen.

Laden von XML-Daten

Übertragen von XML-Daten von SQL Server 2000 zu SQL Server 2005

Zum Übertragen von XML-Daten zu SQL Server 2005 gibt es verschiedene Möglichkeiten, z. B.:

  • Wenn die Daten in einer [n]text- oder image-Spalte in einer SQL Server 2000-Datenbank vorliegen, können Sie die Tabelle mithilfe von SQL Server 2005 Integration Services (SSIS) in eine SQL Server 2005-Datenbank importieren. Ändern Sie den Spaltentyp mithilfe der ALTER TABLE-Anweisung zu XML.
  • Sie können die Daten mithilfe von bcp out mit einem Massenkopiervorgang aus SQL Server 2000 kopieren und anschließend mithilfe von bcp in mit einem Masseneinfügungsvorgang in die SQL Server 2005-Datenbank einfügen.
  • Wenn Sie über Daten in relationalen Spalten in einer SQL Server 2000-Datenbank verfügen, erstellen Sie eine neue Tabelle in einer [n]text-Spalte und optional eine Primärschlüsselspalte für einen Zeilenbezeichner. Rufen Sie mithilfe clientseitiger Programmierung den XML-Code ab, der mit FOR XML auf dem Server generiert wurde, und schreiben Sie ihn in die [n]text-Spalte. Verwenden Sie dann die oben erwähnten Techniken, um die Daten in eine SQL Server 2005-Datenbank zu übertragen. Sie können den XML-Code auch direkt in eine XML-Spalte in der SQL Server 2005-Datenbank schreiben.
Beispiel: Ändern des Spaltentyps zu XML

Angenommen, Sie möchten den Typ einer [n]text- oder image-Spalte XYZ in Tabelle R zu untypisiertem XML ändern. Diese Änderung des Typs wird durch die folgende Anweisung bewirkt:

ALTER TABLE R ALTER COLUMN XYZ XML
  • Das Ziel kann typisiertes XML sein, wenn dieser Typ erforderlich ist, indem Sie eine XML-Schemaauflistung angeben.

Massenladen von XML-Daten

Sie können XML-Daten mit einem Massenladevorgang auf den Server laden, indem Sie die Massenladefunktionen von SQL Server verwenden, z. B. bcp. Mit OPENROWSET können Sie Daten aus Dateien in eine XML-Spalte laden. Das folgende Beispiel veranschaulicht diesen Punkt.

Beispiel: Laden von XML-Daten aus Dateien

Dieses Beispiel zeigt, wie eine Zeile in Tabelle T eingefügt wird. Der Wert der XML-Spalte wird aus der Datei C:\MyFile\xmlfile.xml als CLOB geladen, und die integer-Spalte erhält den Wert 10.

INSERT INTO T
SELECT 10, xCol
FROM    (SELECT *    
    FROM OPENROWSET (BULK 'C:\MyFile\xmlfile.xml', SINGLE_CLOB) 
 AS xCol) AS R(xCol)

Textcodierung

SQL Server 2005 speichert XML-Daten im Unicode (UTF-16)-Format. Die vom Server abgerufenen XML-Daten liegen UTF-16-codiert vor. Wenn Sie eine andere Codierung wünschen, müssen Sie die erforderliche Konvertierung für die abgerufenen Daten ausführen. Manchmal können die XML-Daten in einer abweichenden Codierung vorliegen. Wenn das der Fall ist, müssen Sie beim Laden der Daten mit großer Sorgfalt vorgehen. Beispiel:

  • Wenn Ihre Text-XML-Daten in Unicode (UCS-2, UTF-16) vorliegen, können Sie sie problemlos einer XML-Spalte, einer XML-Variablen oder einem XML-Parameter zuweisen.
  • Wenn die Codierung nicht Unicode ist und aufgrund der Quellcodeseite implizit ist, sollte die Zeichenfolgencodeseite in der Datenbank den Codepunkten gleichen oder mit den Codepunkten kompatibel sein, die Sie laden wollen. Verwenden Sie falls erforderlich COLLATE. Wenn keine solche Servercodeseite vorhanden ist, müssen Sie eine explizite XML-Deklaration mit der richtigen Codierung hinzufügen.
  • Verwenden Sie entweder den varbinary()-Typ, der keinerlei Interaktion mit Codeseiten aufweist, oder einen Zeichenfolgentyp der entsprechenden Codeseite, damit eine explizite Codierung verwendet wird. Weisen Sie anschließend die Daten einer XML-Spalte, einer XML-Variablen oder einem XML-Parameter zu.
Beispiel: Explizites Angeben einer Codierung

Angenommen, Sie besitzen das XML-Dokument vcdoc, das im Datentyp varchar(max) gespeichert ist und keine explizite XML-Deklaration aufweist. Mit der folgenden Anweisung wird eine XML-Deklaration mit der Codierung "iso8859-1" hinzugefügt, das XML-Dokument verkettet, das Ergebnis in varbinary(max) umgewandelt, sodass die Bytedarstellung erhalten bleibt, und das Ergebnis schließlich in XML umgewandelt. Das ermöglicht es dem XML-Prozessor, die Daten entsprechend der angegebenen Codierung "iso8859-1" zu analysieren und die entsprechende UTF-16-Darstellung für Zeichenfolgenwerte zu generieren.

SELECT CAST( 
CAST (('<?xml version="1.0" encoding="iso8859-1"?>'+ vcdoc) AS VARBINARY (MAX)) 
 AS XML)

XQuery und Typrückschluss

Das in Transact-SQL eingebettete XQuery ist die Sprache, die zum Abfragen des xml-Datentyps unterstützt wird. Diese Sprache wird durch das World Wide Web Consortium (W3C) entwickelt, an dem neben Microsoft alle wichtigen Datenbankhersteller beteiligt sind. Sie schließt XPath Version 2.0 als Navigationssprache ein. Für den xml-Datentyp sind auch Sprachkonstrukte zur Datenänderung verfügbar. Weitere Informationen zu den in SQL Server unterstützten XQuery-Konstrukten, -Funktionen und -Operatoren finden Sie unter XQuery-Funktionen für den xml-Datentyp.

Fehlermodell

Von syntaktisch fehlerhaften XQuery-Ausdrücken und XML DML-Anweisungen werden Kompilierungsfehler zurückgegeben. In der Kompilierungsphase wird die Richtigkeit des statischen Typs von XQuery-Ausdrücken und von DML-Anweisungen überprüft, und es werden XML-Schemas für Typrückschlüsse für typisiertes XML verwendet. Es werden statische Typfehler ausgelöst, wenn ein Ausdruck aufgrund eines Verstoßes gegen die Typsicherheit zur Laufzeit fehlschlagen könnte. Beispiele für statische Fehler sind das Hinzufügen einer Zeichenfolge zu einer ganzen Zahl und das Abfragen eines nicht vorhandenen Knotens für typisierte Daten.

In Abweichung vom W3C-Standard werden XQuery-Laufzeitfehler in leere Sequenzen umgewandelt. Diese Sequenzen können je nach Aufrufkontext als leere XML-Daten oder als NULL-Wert an das Abfrageergebnis übergeben werden.

Die explizite Umwandlung in den richtigen Typ ermöglicht Benutzern das Umgehen von statischen Fehlern, obwohl dabei Laufzeitumwandlungsfehler in leere Sequenzen transformiert werden.

Die folgenden Abschnitte beschreiben die Typüberprüfung im Detail.

Singleton-Überprüfungen

Positionsschritte, Funktionsparameter und Operatoren, die Singleton-Elemente benötigen, geben einen Fehler zurück, wenn der Compiler nicht ermitteln kann, ob zur Laufzeit ein Singleton-Element sichergestellt ist. Dieses Problem tritt häufig bei nicht typisierten Daten auf. So erfordert z. B. die Suche eines Attributs ein übergeordnetes Singleton-Element. Dabei ist eine Ordinalzahl ausreichend, die einen einzelnen übergeordneten Knoten auswählt. Die Auswertung einer node()-value()-Kombination zum Extrahieren von Attributwerten erfordert möglicherweise keine Angabe der Ordinalzahl. Dies ist im nächsten Beispiel dargestellt.

Beispiel: Bekanntes Singleton

In diesem Beispiel generiert die nodes()-Methode eine getrennte Zeile für jedes <book>-Element. Die value()-Methode, die für einen <book>-Knoten ausgewertet wird, extrahiert den Wert von @genre und ist – da es sich um ein Attribut handelt – ein Singleton.

SELECT nref.value('@genre', 'varchar(max)') LastName
FROM   T CROSS APPLY xCol.nodes('//book') AS R(nref)

Das XML-Schema wird zur Typprüfung von typisiertem XML verwendet. Wenn ein Knoten im XML-Schema als ein Singleton angegeben ist, verwendet der Compiler diese Informationen, und es tritt kein Fehler auf. Ansonsten ist eine Ordinalzahl erforderlich, die einen einzelnen Knoten auswählt. Insbesondere das Verwenden der descendant-or-self-Achse (//), wie z. B. in /book//title, führt zum Verlust des Singleton-Kardinalitätsrückschlusses für das <title>-Element, selbst wenn dieser vom XML-Schema angegeben ist. Deshalb sollten Sie ihn als (/book//title)[1] umschreiben.

Sie müssen sich des Unterschiedes zwischen //first-name[1] und (//first-name)[1] für die Typüberprüfung bewusst sein. Der erste Ausdruck gibt eine Sequenz von <first-name>-Knoten zurück, in denen jeder Knoten der am weitesten links befindliche <first-name>-Knoten innerhalb seiner gleichgeordneten Elemente ist. Der zweite Ausdruck gibt den ersten Singleton-<first-name>-Knoten in Dokumentreihenfolge in der XML-Instanz zurück.

Beispiel: Verwenden von value()

Die folgende Abfrage für eine nicht typisierte XML-Spalte führt zu einem statischen Kompilierungsfehler. Das liegt daran, dass value() einen Singleton-Knoten als das erste Argument erwartet und der Compiler nicht ermitteln kann, ob zur Laufzeit nur ein einzelner <last-name>-Knoten auftritt.

SELECT xCol.value('//author/last-name', 'nvarchar(50)') LastName
FROM   T

Es folgt eine Projektmappe, die Sie in Betracht ziehen könnten:

SELECT xCol.value('//author/last-name[1]', 'nvarchar(50)') LastName
FROM   T

Allerdings führt diese Projektmappe nicht zum Auflösen des Fehlers, weil mehrere <author>-Knoten in jeder XML-Instanz auftreten können. Die folgende umgeschriebene Version ist jedoch funktionsfähig:

SELECT xCol.value('(//author/last-name/text())[1]', 'nvarchar(50)') LastName
FROM   T

Diese Abfrage gibt den Wert des ersten <last-name>-Elements in jeder XML-Instanz zurück.

Übergeordnete Achse

Wenn der Typ eines Knotens nicht bestimmt werden kann, wird er zu anyType. Dieser wird nicht implizit in irgendeinen anderen Typ umgewandelt. Dass tritt am deutlichsten während der Navigation mithilfe der übergeordneten Achse auf, z. B. von xCol.query('/book/@genre/../price'). Der Typ des übergeordneten Knotens wird als anyType bestimmt. Ein Element kann auch in einem XML-Schema als anyType definiert sein. In beiden Fällen führt der Verlust der präziseren Typinformationen häufig zu statischen Typfehlern und erfordert das explizite Umwandeln von atomaren Werten in ihren speziellen Typ.

data()-, text()- und string()-Accessoren

XQuery verfügt über eine Funktion fn:data() zum Extrahieren skalarer, extrahierter Werte aus Knoten, eine Knotentestfunktion text() zum Zurückgeben von Textknoten sowie die Funktion fn:string(), die den Zeichenfolgenwert eines Knotens zurückgibt. Ihre Verwendung kann verwirrend sein. Es folgen die Richtlinien zu ihrer ordnungsgemäßen Verwendung in SQL Server 2005. Die XML-Instanz <age>12</age> wird zur Veranschaulichung verwendet.

  • Nicht typisiertes XML: Der Pfadausdruck /age/text() gibt den Textknoten "12" zurück. Die Funktion fn:data(/age) gibt den Zeichenfolgenwert "12" zurück, was auch für fn:string(/age) gilt.
  • Typisiertes XML: Der Ausdruck /age/text() gibt einen statischen Fehler für jedes einfache typisierte <age>-Element zurück. Dagegen gibt fn:data(/age) die ganze Zahl 12 zurück. Die Funktion fn:string(/age) führt zur Zeichenfolge "12".

Funktionen und Operatoren für Union-Typen

Union-Typen erfordern aufgrund der Typüberprüfung eine sorgfältige Handhabung. In den folgenden Beispielen sind zwei der Probleme dargestellt.

Beispiel: Funktion für Union-Typ

Stellen Sie sich eine Elementdefinition für <r> eines Union-Typs vor:

<xs:element name="r">
<xs:simpleType>
   <xs:union memberTypes="xs:int xs:float xs:double"/>
</xs:simpleType>
</xs:element>

Im XQuery-Kontext gibt die "Durchschnittsfunktion" fn:avg (//r) einen statischen Fehler zurück, weil der XQuery-Compiler keine Werte verschiedener Typen (xs:int, xs:float oder xs:double) für die <r>-Elemente im Argument von fn:avg() hinzufügen kann. Um dieses Problem zu beheben, müssen Sie den Funktionsaufruf als fn:avg(for $r in //r return $r cast as xs:double ?) umschreiben.

Beispiel: Operator für Union-Typ

Die Additionsoperation ('+') erfordert präzise Typen der Operanden. Als Ergebnis gibt der Ausdruck (//r)[1] + 1 einen statischen Fehler zurück, der die zuvor beschriebene Typdefinition für das Element <r> aufweist. Eine mögliche Lösung besteht im Umschreiben des Ausdrucks als as (//r)[1] cast as xs:int? +1, wobei das "?" das Auftreten von 0 oder 1 anzeigt. SQL Server 2005 erfordert "cast as" mit "?", weil jede Umwandlung die leere Sequenz als ein Ergebnis von Laufzeitfehlern verursachen kann.

Value(), Nodes() und OpenXML()

Sie können mehrere value()-Methoden für den xml-Datentyp in einer SELECT-Klausel verwenden, um ein Rowset aus extrahierten Werten zu generieren. Die nodes()-Methode ergibt einen internen Verweis für jeden ausgewählten Knoten, der für zusätzliche Abfragen verwendet werden kann. Die Kombination der Methoden nodes() und value() kann beim Generieren des Rowsets effizienter sein, wenn es über mehrere Spalten verfügt und möglicherweise auch, wenn die zu ihrer Generierung verwendeten Pfadausdrücke komplex sind.

Die nodes()-Methode ergibt Instanzen eines speziellen xml-Datentyps, wobei bei jedem der Kontext auf einen unterschiedlichen ausgewählten Knoten festgelegt ist. Diese Art der XML-Instanz unterstützt query()-, value()-, nodes()- und exist()-Methoden und kann in count(*)-Aggregationen verwendet werden. Alle anderen Verwendungen verursachen einen Fehler.

Beispiel: Verwenden von nodes()

Angenommen, Sie wollen die Vornamen und Nachnamen von Autoren extrahieren, und der Vorname soll nicht "David" sein. Außerdem wollen Sie diese Informationen als ein Rowset extrahieren, das die beiden Spalten FirstName und LastName enthält. Durch Verwenden der Methoden nodes() und value() können Sie dieses Ziel erreichen, wie das im folgenden Beispiel gezeigt wird:

SELECT nref.value('(first-name/text())[1]', 'nvarchar(50)') FirstName,
       nref.value('(last-name/text())[1]', 'nvarchar(50)') LastName
FROM   T CROSS APPLY xCol.nodes('//author') AS R(nref)
WHERE  nref.exist('first-name[. != "David"]') = 1

In diesem Beispiel ergibt nodes('//author') ein Rowset aus Verweisen auf <author>-Elemente für jede XML-Instanz. Die Vor- und Nachnamen der Autoren werden abgerufen, indem die value()-Methoden im Verhältnis zu diesen Verweisen ausgewertet werden.

SQL Server 2000 bietet die Möglichkeit zum Generieren eines Rowsets aus einer XML-Instanz durch Verwenden von OpenXml(). Sie können das relationale Schema für das Rowset angeben sowie, wie die Werte in der XML-Instanz den Spalten im Rowset zugeordnet sind.

Beispiel: Verwenden von OpenXml() für den xml-Datentyp

Die Abfrage aus dem vorherigen Beispiel kann mithilfe von OpenXml() umgeschrieben werden, wie das im folgenden Beispiel gezeigt wird. Dies geschieht durch Erstellen eines Cursors, der jede XML-Instanz in eine XML-Variable einliest und dann für OpenXML auf sie anwendet:

DECLARE name_cursor CURSOR
FOR
   SELECT xCol 
   FROM   T
OPEN name_cursor
DECLARE @xmlVal XML
DECLARE @idoc int
FETCH NEXT FROM name_cursor INTO @xmlVal

WHILE (@@FETCH_STATUS = 0)
BEGIN
   EXEC sp_xml_preparedocument @idoc OUTPUT, @xmlVal
   SELECT   *
   FROM   OPENXML (@idoc, '//author')
          WITH (FirstName  varchar(50) 'first-name',
                LastName   varchar(50) 'last-name') R
   WHERE  R.FirstName != 'David'

   EXEC sp_xml_removedocument @idoc
   FETCH NEXT FROM name_cursor INTO @xmlVal
END
CLOSE name_cursor
DEALLOCATE name_cursor 

OpenXml() erstellt eine arbeitsspeicherinterne Darstellung und verwendet Arbeitstabellen anstelle des Abfrageprozessors. Sie greift nicht auf das XQuery-Modul zurück, sondern auf den XPath-Prozessor Version 1.0 von MSXML Version 3.0. Die Arbeitstabellen werden nicht von mehreren Aufrufen an OpenXml() gemeinsam genutzt, selbst auf derselben XML-Instanz nicht. Damit ist ihre Skalierbarkeit eingeschränkt. OpenXml() ermöglicht Ihnen das Zugreifen auf ein Rahmentabellenformat für die XML-Daten, wenn die WITH-Klausel nicht angegeben ist. Außerdem ermöglicht es Ihnen das Verwenden des übrigen XML-Wertes in einer getrennten "Überlaufspalte".

Die Kombination aus den nodes()- und value()-Funktionen sorgt für eine effektive XML-Indizierung. Im Ergebnis kann diese Kombination eine größere Skalierbarkeit als OpenXml aufweisen.

Verwenden von FOR XML zum Generieren von XML für Rowsets

Sie können eine xml-Datentypinstanz aus einem Rowset generieren, indem Sie FOR XML mit der neuen TYPE-Direktive verwenden.

Das Ergebnis kann einer Spalte, einer Variablen oder einem Parameter mit dem xml-Datentyp zugewiesen werden. Außerdem kann FOR XML geschachtelt werden, um jede beliebige hierarchische Struktur zu generieren. Damit kann geschachteltes FOR XML viel bequemer geschrieben werden als FOR XML EXPLICIT, es zeigt aber möglicherweise eine weniger gute Leistung bei tiefen Hierarchien. FOR XML führt auch einen neuen PATH-Modus ein. Dieser neue Modus gibt den Pfad im XML-Baum an, in dem der Wert einer Spalte erscheint.

Die neue FOR XML TYPE-Direktive kann verwendet werden, um schreibgeschützte XML-Sichten für relationale Daten mit SQL-Syntax zu definieren. Die Sicht kann mit SQL-Anweisungen und eingebettetem XQuery abgefragt werden, wie das im folgenden Beispiel gezeigt wird. Sie können auf diese SQL-Sichten auch in gespeicherten Prozeduren verweisen.

Beispiel: SQL-Sicht zum Zurückgeben des generiertem xml-Datentyps

Die folgende SQL-Sichtdefinition erstellt eine XML-Sicht für eine relationale Spalte pk und ruft die Buchautoren aus einer XML-Spalte ab.

CREATE VIEW V (xmlVal) AS
SELECT pk, xCol.query('/book/author')
FROM   T
FOR XML AUTO, TYPE

Die V-Sicht enthält eine einzelne Zeile mit einem einzelnen columnxmlVal des XML-Typs . . Diese kann wie eine reguläre xml-Datentypinstanz abgefragt werden. Beispielsweise gibt die folgende Abfrage den Autor zurück, dessen Vorname "David" ist:

SELECT xmlVal.query('//author[first-name = "David"]')
FROM   V

SQL-Sichtdefinitionen ähneln in gewisser Weise XML-Sichten, indem Sie durch Verwenden von Schemas mit Anmerkungen erstellt werden. Es gibt jedoch auch wichtige Unterschiede. Die SQL-Sichtdefinition ist schreibgeschützt und muss mit eingebettetem XQuery bearbeitet werden. Die XML-Sichten werden ebenfalls durch Verwenden von Schemas mit Anmerkungen erstellt. Darüber hinaus materialisiert die SQL-Sicht das XML-Ergebnis, bevor der XQuery-Ausdruck angewendet wird, während die XPath-Abfragen für XML-Sichten SQL-Abfragen für die zugrunde liegenden Tabellen auswerten.

Hinzufügen von Geschäftslogik

Ihre Geschäftslogik kann auf verschiedene Art und Weise den XML-Daten hinzugefügt werden:

  • Sie können Zeilen- oder Spalteneinschränkungen schreiben, um beim Einfügen und Bearbeiten von XML-Daten domänenspezifische Einschränkungen zu erzwingen.
  • Sie können einen Trigger für die XML-Spalte schreiben, der ausgelöst wird, wenn Sie Werte in die Spalte einfügen oder aktualisieren. Der Trigger kann domänenspezifische Überprüfungsregeln enthalten oder Eigenschaftentabellen auffüllen.
  • Sie können SQLCLR-Funktionen in verwaltetem Code schreiben, an den Sie XML-Werte übergeben, und die vom System.Xml-Namespace bereitgestellten Möglichkeiten zur XML-Verarbeitung verwenden. Ein Beispiel hierfür ist die Anwendung der XSL-Transformation auf XML-Daten. Alternativ können Sie den XML-Code in eine oder mehrere verwaltete Klassen deserialisieren und diese mithilfe von verwaltetem Code verarbeiten.
  • Sie können gespeicherte Transact-SQL-Prozeduren und -Funktionen schreiben, mit denen das Verarbeiten der XML-Spalte für Ihre Unternehmensanforderungen gestartet wird.
Beispiel: Anwenden der XSL-Transformation

Angenommen, eine CLR-Funktion TransformXml() nimmt eine xml-Datentypinstanz und eine in einer Datei gespeicherte XSL-Transformation an, wendet die Transformation auf die XML-Daten an und gibt dann den transformierten XML-Code im Ergebnis zurück. Es folgt eine Skeleton-Funktion, die in C# geschrieben ist:

public static SqlXml TransformXml (SqlXml XmlData, string xslPath) {
   // Load XSL transformation
   XslCompiledTransform xform = new XslCompiledTransform();
   XPathDocument xslDoc = new XPathDocument (xslPath);
   xform.Load(xslDoc);

   // Load XML data 
   XPathDocument xDoc = new XPathDocument (XmlData.CreateReader());

   // Return the transformed value
   MemoryStream xsltResult = new MemoryStream();
   xform.Transform(xDoc, null, xsltResult);
   SqlXml retSqlXml = new SqlXml(xsltResult);
   return (retSqlXml);
} 

Nachdem die Assembly registriert und eine benutzerdefinierte Transact-SQL-Funktion erstellt wurde (SqlXslTransform() entsprechend TransformXml()), kann die Funktion von Transact-SQL aus aufgerufen werden, wie in der folgenden Abfrage gezeigt.

SELECT SqlXslTransform (xCol, 'C:\MyFile\xsltransform.xsl')
FROM    T
WHERE  xCol.exist('/book/title/text()[contains(.,"custom")]') =1

Das Abfrageergebnis enthält ein Rowset der transformierten XML-Daten.

SQLCLR erweitert die Möglichkeiten zum Zerlegen der XML-Daten in Tabellen oder zum Heraufstufen von Eigenschaften sowie die Möglichkeiten zum Abfragen von XML-Daten durch Verwenden von verwalteten Klassen im System.Xml-Namespace. Weitere Informationen finden Sie in der SQL Server-Onlinedokumentation und in der .NET Framework SDK-Dokumentation.

Domänenübergreifende Abfragen

Wenn sich die Daten in einer Kombination aus relationalen und xml-Datentypspalten befinden, möchten Sie möglicherweise Abfragen schreiben, die das Verarbeiten von relationalen und XML-Daten kombinieren. Sie können z. B. die Daten in relationalen und XML-Spalten in eine xml-Datentypinstanz konvertieren, indem Sie FOR XML verwenden und diese Instanz mithilfe von XQuery abfragen. Im Gegensatz dazu können Sie ein Rowset aus XML-Werten generieren und dieses Rowset mithilfe von Transact-SQL abfragen.

Eine praktischere und effizientere Möglichkeit zum Schreiben von domänenübergreifenden Abfragen besteht darin, den Wert einer SQL-Variablen oder -Spalte in XQuery- oder XML DML-Ausdrücken zu verwenden:

  • Mithilfe von sql:variable() können Sie den Wert einer SQL-Variablen in Ihrem XQuery- oder XML DML-Ausdruck verwenden.
  • Mithilfe von sql:column() können Sie die Werte aus einer SQL-Spalte in Ihrem XQuery- oder XML DML-Ausdruck verwenden.

Diese beiden Vorgehensweisen ermöglichen Anwendungen das Parametrisieren von Abfragen, wie das im nächsten Beispiel gezeigt wird. Allerdings sind in sql:variable() und sql:column() keine XML- und benutzerdefinierten Typen zulässig.

Beispiel: Domänenübergreifende Abfrage mithilfe von sql:variable()

Die folgende Abfrage ist eine geänderte Version der Abfrage aus "Beispiel: Abfragen für eine berechnete Spalte auf der Basis der xml-Datentypmethoden". In der folgenden Version wird eine bestimmte ISBN mithilfe einer SQL-Variablen @isbn übergeben. Durch Ersetzen der Konstante durch sql:variable() kann die Abfrage zum Suchen nach jeder ISBN und nicht nur nach der ISBN 0-7356-1588-2 verwendet werden.

DECLARE @isbn varchar(20)
SET     @isbn = '0-7356-1588-2'
SELECT  xCol
FROM    T
WHERE   xCol.exist ('/book/@ISBN[. = sql:variable("@isbn")]') = 1

sql:column() kann auf ähnliche Weise verwendet werden und bietet weitere Vorteile. Indizes für die Spalte können aus Effizienzgründen verwendet werden, was durch den kostenbasierten Abfrageoptimierer entschieden wird. Außerdem kann die berechnete Spalte zum Speichern einer heraufgestuften Eigenschaft verwendet werden.

Katalogsichten für die systemeigene XML-Unterstützung

Katalogsichten stellen Metadateninformationen zur XML-Verwendung bereit. Davon werden einige im folgenden Abschnitt beschrieben.

XML-Indizes

XML-Indexeinträge erscheinen in der Katalogsicht sys.indexes, wobei der Index als "Typ" 3 besitzt. Die Namenspalte enthält den Namen des XML-Indexes.

XML-Indizes sind auch in der Katalogsicht sys.xml_indexes aufgezeichnet. Diese enthält alle Spalten von sys.indexes und einige spezielle Spalten, die für XML-Indizes nützlich sind. Der Wert NULL in der Spalte secondary_type zeigt einen primären XML-Index an; die Werte 'P', 'R' und 'V' stehen für sekundäre PATH-, PROPERTY- bzw. VALUE-XML-Indizes.

Der von XML-Indizes verwendete Speicherplatz kann in der Tabellenwertfunktion sys.dm_db_index_physical_stats gefunden werden. Sie stellt für alle Indextypen Informationen bereit, wie z. B. zur Anzahl der belegten Speicherseiten, zur durchschnittlichen Zeilengröße in Byte und zur Anzahl der Datensätze. Dieses schließt auch XML-Indizes ein. Diese Informationen sind für jede Datenbankpartition verfügbar. XML-Indizes verwenden das Partitionierungsschema und die Partitionierungsfunktion der Basistabelle.

Abrufen von XML-Schemaauflistungen

XML-Schemaauflistungen sind in der Katalogsicht sys.xml_schema_collections aufgeführt. Die XML-Schemaauflistung "sys" wird durch das System definiert. Sie enthält die vordefinierten Namespaces, die in allen benutzerdefinierten XML-Schemaauflistungen verwendet werden können, ohne dass sie explizit geladen werden müssen. Diese Auflistung enthält die Namespaces für xml, xs, xsi, fn und xdt. Zwei weitere Katalogsichten sind sys.xml_schema_namespaces, die alle Namespaces innerhalb jeder Schemaauflistung aufführt, und sys.xml_components, die alle XML-Schemakomponenten innerhalb jedes XML-Schemas aufführt.

Die integrierte Funktion XML_SCHEMA_NAMESPACE, schemaName, XmlSchemacollectionName, namespace-uri, ergibt eine xml-Datentypinstanz. Diese Instanz enthält XML-Schemafragmente für Schemas, die in einer XML-Schemaauflistung enthalten sind, mit Ausnahme der vordefinierten XML-Schemas.

Es gibt folgende Möglichkeiten, um den Inhalt einer XML-Schemaauflistung aufzuführen:

  • Schreiben Sie Transact-SQL-Abfragen zur jeweiligen Katalogsicht für XML-Schemaauflistungen.
  • Verwenden Sie die integrierte Funktion XML_SCHEMA_NAMESPACE(). Auf das Ergebnis dieser Funktion können Sie die xml-Datentypmethoden anwenden. Allerdings können Sie dabei die zugrunde liegenden XML-Schemas nicht ändern.

Diese Möglichkeiten werden in den folgenden Beispielen veranschaulicht.

Beispiel: Aufführen der XML-Namespaces in einer XML-Schemaauflistung

Verwenden Sie die folgende Abfrage für die XML-Schemaauflistung "myCollection":

SELECT XSN.name
FROM    sys.xml_schema_collections XSC JOIN sys.xml_schema_namespaces XSN
    ON (XSC.xml_collection_id = XSN.xml_collection_id)
WHERE    XSC.name = 'myCollection'   
Beispiel: Aufführen des Inhalts einer XML-Schemaauflistung

Mit der folgenden Anweisung wird der Inhalt der XML-Schemaauflistung "myCollection" innerhalb des relationalen Schemas dbo aufgeführt.

SELECT XML_SCHEMA_NAMESPACE (N'dbo', N'myCollection')

Einzelne XML-Schemas innerhalb der Auflistung können als xml-Datentypinstanzen abgerufen werden, indem der Zielnamespace als drittes Argument für XML_SCHEMA_NAMESPACE() angegeben wird. Dies wird im folgenden Beispiel gezeigt.

Beispiel: Ausgeben eines angegebenen Schemas für eine XML-Schemaauflistung

Mit der folgenden Anweisung wird das XML-Schema mit dem Zielnamespace "https://www.microsoft.com/books" aus der XML-Schemaauflistung "myCollection" innerhalb dem relationalen Schema dbo ausgegeben.

SELECT XML_SCHEMA_NAMESPACE (N'dbo', N'myCollection', 
N'https://www.microsoft.com/books')

Abfragen von XML-Schemas

Es gibt folgende Möglichkeiten, um XML-Schemas, die Sie in XML-Schemaauflistungen geladen haben, abzufragen:

  • Schreiben Sie Transact-SQL-Abfragen zu Katalogsichten für XML-Schemaauflistungen.
  • Erstellen Sie eine Tabelle, die eine xml-Datentypspalte enthält, um die XML-Schemas zu speichern, und laden Sie diese auch in das XML-Typsystem. Sie können dann diese XML-Spalte abfragen, indem Sie xml-Datentypmethoden verwenden. Für diese Spalte können Sie auch einen XML-Index erstellen. Allerdings muss die Anwendung für diese Vorgehensweise die Konsistenz zwischen den in der XML-Spalte gespeicherten XML-Schemas und dem XML-Typsystem beibehalten. Wenn Sie z. B. den XML-Schemanamespace aus dem XML-Typsystem löschen, müssen Sie ihn auch aus der Tabelle löschen, damit die Konsistenz beibehalten wird.

Siehe auch

Verweis

Verwalten von XML-Schemaauflistungen auf dem Server
XQuery-Funktionen für den xml-Datentyp

Konzepte

XML-Datentyp

Andere Ressourcen

sys.dm_db_index_physical_stats
Einführung in die Volltextsuche

Hilfe und Informationen

Informationsquellen für SQL Server 2005