Anmerkung
Der Zugriff auf diese Seite erfordert eine Genehmigung. Du kannst versuchen, dich anzumelden oder die Verzeichnisse zu wechseln.
Der Zugriff auf diese Seite erfordert eine Genehmigung. Du kannst versuchen , die Verzeichnisse zu wechseln.
Gilt für:SQL Server
XQuery definiert die Iterationssyntax FLWOR. FLWOR ist das Akronym für for, let, where, order by und return.
Eine FLWOR-Anweisung besteht aus den folgenden Teilen:
Eine oder
FORmehrere Klauseln, die eine oder mehrere Iteratorvariablen an Eingabesequenzen binden.Eingabesequenzen können andere XQuery-Ausdrücke wie z. B. XPath-Ausdrücke sein. Sie sind entweder Sequenzen von Knoten oder Sequenzen von Atomwerten. Sequenzen atomarer Werte können mithilfe von Literalen oder Konstruktorfunktionen erstellt werden. Konstruierte XML-Knoten sind nicht als Eingabesequenzen in SQL Server zulässig.
Einer optionalen
let-Klausel. Diese Klausel weist der angegebenen Variable für eine bestimmte Iteration einen Wert zu. Der zugewiesene Ausdruck kann ein XQuery-Ausdruck, z. B. ein XPath-Ausdruck sein, und entweder eine Sequenz aus Knoten oder eine Sequenz aus atomaren Werten zurückgeben. Sequenzen aus atomaren Werten können mithilfe von Literalen oder Konstruktorfunktionen erstellt werden. Konstruierte XML-Knoten sind nicht als Eingabesequenzen in SQL Server zulässig.Einer Iteratorvariablen. Diese Variable kann eine optionale Typassertion mithilfe des
as-Schlüsselworts besitzen.Einer optionalen
where-Klausel. Diese Klausel wendet ein Filterprädikat auf die Iteration an.Einer optionalen
order by-Klausel.Einem
return-Ausdruck. Der Ausdruck in derreturn-Klausel erstellt das Ergebnis der FLWOR-Anweisung.
Die folgende Abfrage durchläuft beispielsweise die <Step> Elemente an der ersten Fertigungsposition und gibt den Zeichenfolgenwert der <Step> Knoten zurück:
DECLARE @x AS XML;
SET @x = '<ManuInstructions ProductModelID="1" ProductModelName="SomeBike" >
<Location LocationID="L1" >
<Step>Manu step 1 at Loc 1</Step>
<Step>Manu step 2 at Loc 1</Step>
<Step>Manu step 3 at Loc 1</Step>
</Location>
<Location LocationID="L2" >
<Step>Manu step 1 at Loc 2</Step>
<Step>Manu step 2 at Loc 2</Step>
<Step>Manu step 3 at Loc 2</Step>
</Location>
</ManuInstructions>';
SELECT @x.query('
for $step in /ManuInstructions/Location[1]/Step
return string($step)
');
Das Ergebnis lautet wie folgt:
Manu step 1 at Loc 1 Manu step 2 at Loc 1 Manu step 3 at Loc 1
Die folgende Abfrage ähnelt der vorherigen Abfrage, mit der Ausnahme, dass sie für die Spalte "Anweisungen", eine typierte XML-Spalte, der Tabelle "ProductModel" angegeben ist. Die Abfrage durchläuft alle Fertigungsschritte, <step> Elemente am ersten Arbeitsplatzstandort für ein bestimmtes Produkt.
SELECT Instructions.query('
declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
for $Step in //AWMI:root/AWMI:Location[1]/AWMI:step
return
string($Step)
') AS Result
FROM Production.ProductModel
WHERE ProductModelID = 7;
Beachten Sie hinsichtlich der vorherigen Abfrage Folgendes:
$Stepist die Iteratorvariable.Der generiert die Eingabesequenz. Diese Sequenz ist die Sequenz der <
step> untergeordneten Elementknoten des ersten <Location> Elementknotens.Die optionale Prädikatklausel wird
wherenicht verwendet.Der
returnAusdruck gibt einen Zeichenfolgenwert aus dem <step> Element zurück.
Die Zeichenfolgenfunktion (XQuery) wird verwendet, um den Zeichenfolgenwert des <step> Knotens abzurufen.
Dies ist das Teilergebnis:
Insert aluminum sheet MS-2341 into the T-85A framing tool.
Attach Trim Jig TJ-26 to the upper and lower right corners of
the aluminum sheet. ....
Dies sind Beispiele für andere zulässige Eingabesequenzen:
DECLARE @x AS XML;
SET @x = '';
SELECT @x.query('
for $a in (1, 2, 3)
return $a');
-- result = 1 2 3
DECLARE @x AS XML;
SET @x = '';
SELECT @x.query('
for $a in
for $b in (1, 2, 3)
return $b
return $a');
-- result = 1 2 3
DECLARE @x AS XML;
SET @x = '<ROOT><a>111</a></ROOT>';
SELECT @x.query('
for $a in (xs:string( "test"), xs:double( "12" ), data(/ROOT/a ))
return $a');
-- result test 12 111
In SQL Server sind heterogene Sequenzen nicht zulässig. Insbesondere Sequenzen, die eine Mischung aus atomischen Werten und Knoten enthalten, sind nicht zulässig.
Iteration wird häufig zusammen mit der XML-Konstruktionssyntax (XQuery) bei der Transformation von XML-Formaten verwendet, wie in der nächsten Abfrage gezeigt.
In der AdventureWorks-Beispieldatenbank weisen die in der Instructions Spalte der Production.ProductModel Tabelle gespeicherten Fertigungsanweisungen das folgende Formular auf:
<Location LocationID="10" LaborHours="1.2"
SetupHours=".2" MachineHours=".1">
<step>describes 1st manu step</step>
<step>describes 2nd manu step</step>
...
</Location>
...
Mit der folgenden Abfrage wird ein neuer XML-Code erstellt, der die <Location> Elemente mit den Speicherortattributen des Arbeitscenters enthält, die als untergeordnete Elemente zurückgegeben werden:
<Location>
<LocationID>10</LocationID>
<LaborHours>1.2</LaborHours>
<SetupHours>.2</SetupHours>
<MachineHours>.1</MachineHours>
</Location>
...
Hier ist die Abfrage:
SELECT Instructions.query('
declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
for $WC in /AWMI:root/AWMI:Location
return
<Location>
<LocationID> { data($WC/@LocationID) } </LocationID>
<LaborHours> { data($WC/@LaborHours) } </LaborHours>
<SetupHours> { data($WC/@SetupHours) } </SetupHours>
<MachineHours> { data($WC/@MachineHours) } </MachineHours>
</Location>
') AS Result
FROM Production.ProductModel
WHERE ProductModelID = 7;
Beachten Sie die folgenden Überlegungen aus der vorherigen Abfrage:
Die FLWOR-Anweisung ruft eine Abfolge von <
Location> Elementen für ein bestimmtes Produkt ab.Die Datenfunktion (XQuery) wird verwendet, um den Wert jedes Attributs zu extrahieren, sodass sie dem resultierenden XML-Code als Textknoten und nicht als Attribute hinzugefügt werden.
Der Ausdruck in der
RETURNKlausel erstellt den gewünschten XML-Code.
Dies ist ein Teilergebnis:
<Location>
<LocationID>10</LocationID>
<LaborHours>2.5</LaborHours>
<SetupHours>0.5</SetupHours>
<MachineHours>3</MachineHours>
</Location>
<Location>
...
<Location>
...
Verwenden der let Klausel
Mithilfe der let-Klausel können Sie wiederholte Ausdrücke benennen, auf die Sie durch einen Verweis auf die Variable verweisen können. Der Ausdruck, der einer let-Variable zugewiesen ist, wird jedes Mal in die Abfrage eingefügt wird, wenn in der Abfrage auf die Variable verwiesen wird. Das bedeutet, dass die Anweisung so oft ausgeführt wird, wie auf den Ausdruck verwiesen wird.
In der AdventureWorks2025-Datenbank enthalten die Produktionsanweisungen Informationen zu den erforderlichen Tools und der Position, an der die Tools verwendet werden. Die folgende Abfrage verwendet die let Klausel, um die Tools auflisten, die zum Erstellen eines Produktionsmodells erforderlich sind, sowie die Speicherorte, an denen jedes Tool benötigt wird.
SELECT Instructions.query('
declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
for $T in //AWMI:tool
let $L := //AWMI:Location[.//AWMI:tool[.=data($T)]]
return
<tool desc="{data($T)}" Locations="{data($L/@LocationID)}"/>
') AS Result
FROM Production.ProductModel
WHERE ProductModelID = 7;
Verwenden der where Klausel
Sie können die where Klausel verwenden, um Ergebnisse einer Iteration zu filtern. Dies wird im folgenden Beispiel veranschaulicht.
Bei der Produktion eines Fahrrades durchläuft der Produktionsprozess eine Reihe von Arbeitsplatzstandorten. Jeder Arbeitsplatzstandort definiert eine Sequenz von Produktionsschritten. Die folgende Abfrage ruft nur die Arbeitsplatzstandorte ab, die ein Fahrradmodell fertigen und weniger als drei Produktionsschritte verwenden. Das heißt, sie haben weniger als drei <step> Elemente.
SELECT Instructions.query('
declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
for $WC in /AWMI:root/AWMI:Location
where count($WC/AWMI:step) < 3
return
<Location >
{ $WC/@LocationID }
</Location>
') AS Result
FROM Production.ProductModel
WHERE ProductModelID = 7;
Beachten Sie in der vorhergehenden Abfrage Folgendes:
Das
whereSchlüsselwort verwendet diecount()Funktion, um die Anzahl der <step> untergeordneten Elemente an jedem Arbeitscenterstandort zu zählen.Der
return-Ausdruck erstellt das von Ihnen gewünschte XML aus den Ergebnissen der Iteration.
Das Ergebnis lautet wie folgt:
<Location LocationID="30"/>
Das Ergebnis des Ausdrucks in der where-Klausel wird mithilfe der folgenden Regeln in der angegebenen Reihenfolge in einen booleschen Wert konvertiert. Dies sind identisch mit den Regeln für Prädikate in Pfadausdrücken, mit der Ausnahme, dass ganze Zahlen nicht zulässig sind:
Wenn der
where-Ausdruck eine leere Sequenz zurückgibt, ist der effektive boolesche Wert False.Wenn der
where-Ausdruck einen booleschen Wert vom simple-Typ zurückgibt, ist dieser Wert der effektive boolesche Wert.Wenn der
where-Ausdruck eine Sequenz zurückgibt, die mindestens einen Knoten enthält, ist der effektive boolesche Wert True.Anderenfalls wird ein statischer Fehler ausgelöst.
Mehrere variable Bindung in FLWOR
Sie können einen einzelnen FLWOR-Ausdruck verwenden, um mehrere Variablen an Eingabesequenzen zu binden. Im folgenden Beispiel wird die Abfrage z. B. für eine nicht typisierte xml-Variable angegeben. Der FLOWR-Ausdruck gibt das erste <Step> untergeordnete Element in jedem <Location> Element zurück.
DECLARE @x AS XML;
SET @x = '<ManuInstructions ProductModelID="1" ProductModelName="SomeBike" >
<Location LocationID="L1" >
<Step>Manu step 1 at Loc 1</Step>
<Step>Manu step 2 at Loc 1</Step>
<Step>Manu step 3 at Loc 1</Step>
</Location>
<Location LocationID="L2" >
<Step>Manu step 1 at Loc 2</Step>
<Step>Manu step 2 at Loc 2</Step>
<Step>Manu step 3 at Loc 2</Step>
</Location>
</ManuInstructions>';
SELECT @x.query('
for $Loc in /ManuInstructions/Location,
$FirstStep in $Loc/Step[1]
return
string($FirstStep)
');
Beachten Sie hinsichtlich der vorherigen Abfrage Folgendes:
Der Ausdruck definiert variablen und $.the
forexpression defines$Locand $FirstStepvariables.Die
two-Ausdrücke/ManuInstructions/Locationund$FirstStep in $Loc/Step[1]sind insofern korreliert, als die Werte von$FirstStepvon den Werten von$Locabhängen.Der mit
$Locdem Ausdruck verknüpfte Ausdruck generiert eine Abfolge von <Location> Elementen. Generiert für jedes <Location> Element$FirstStepeine Sequenz von einem <Step> Element, einem Singleton.$Locwird in dem Ausdruck angegeben, der der$FirstStep-Variablen zugeordnet ist.
Das Ergebnis lautet wie folgt:
Manu step 1 at Loc 1
Manu step 1 at Loc 2
Die folgende Abfrage ist ähnlich, mit der Ausnahme, dass sie für die Spalte "Anweisungen", die eingegebene XML-Spalte der ProductModel Tabelle, angegeben ist.
Xml-Konstruktion (XQuery) wird verwendet, um den gewünschten XML-Code zu generieren.
SELECT Instructions.query('
declare default element namespace "https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
for $WC in /root/Location,
$S in $WC/step
return
<Step LocationID= "{$WC/@LocationID }" >
{ $S/node() }
</Step>
') AS Result
FROM Production.ProductModel
WHERE ProductModelID = 7;
Beachten Sie in der vorhergehenden Abfrage Folgendes:
Die
for-Klausel definiert zwei Variablen,$WCund$S. Der Ausdruck, der$WCzugeordnet ist, generiert eine Sequenz von Arbeitsplatzstandorten bei der Fertigung eines Fahrrades eines Fahrradproduktmodells. Der path-Ausdruck, der der$S-Variablen zugeordnet ist, generiert eine Sequenz von Schritten für jede Arbeitsplatzstandort-Sequenz in$WC.Die Return-Anweisung erstellt XML mit einem <
Step> Element, das den Fertigungsschritt und dasLocationIDattribut enthält.Der Declare-Standardelementnamespace wird im XQuery-Prolog verwendet, sodass alle Namespacedeklarationen im resultierenden XML-Code im Element der obersten Ebene angezeigt werden. Auf diese Weise ist das Ergebnis besser lesbar. Weitere Informationen zu Standardnamespaces finden Sie unter Behandeln von Namespaces in XQuery.
Dies ist das Teilergebnis:
<Step xmlns=
"https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions"
LocationID="10">
Insert <material>aluminum sheet MS-2341</material> into the <tool>T-
85A framing tool</tool>.
</Step>
...
<Step xmlns=
"https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions"
LocationID="20">
Assemble all frame components following blueprint
<blueprint>1299</blueprint>.
</Step>
...
Verwenden der order by Klausel
Die Sortierung in XQuery wird mithilfe der order by-Klausel im FLWOR-Ausdruck ausgeführt. Die an die order by Klausel übergebenen Sortierausdrücke müssen Werte zurückgeben, deren Typen für den gt Operator gültig sind. Jeder Sortierausdruck muss zu einer Singletonsequenz mit einem Element führen. Standardmäßig wird die Sortierung in aufsteigender Reihenfolge durchgeführt. Sie können optional die auf- oder absteigende Reihenfolge für jeden Sortierausdruck angeben.
Hinweis
Sortierungsvergleiche für Zeichenfolgenwerte, die von der XQuery-Implementierung in SQL Server ausgeführt werden, werden immer mithilfe der binären Unicode-Codepoint-Sortierung ausgeführt.
Die folgende Abfrage ruft alle Rufnummern für einen bestimmten Kunden aus der AdditionalContactInfo-Spalte ab. Die Ergebnisse werden nach Rufnummer sortiert.
USE AdventureWorks2022;
GO
SELECT AdditionalContactInfo.query('
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
declare namespace aci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
for $a in /aci:AdditionalContactInfo//act:telephoneNumber
order by $a/act:number[1] descending
return $a
') AS Result
FROM Person.Person
WHERE BusinessEntityID = 291;
Der Atomisierungsprozess (XQuery) ruft den Atomwert der <number> Elemente ab, bevor er an order bydiese übergeben wird. Sie können den Ausdruck mithilfe der data() Funktion schreiben, dies ist jedoch nicht erforderlich.
order by data($a/act:number[1]) descending
Das Ergebnis lautet wie folgt:
<act:telephoneNumber xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
<act:number>333-333-3334</act:number>
</act:telephoneNumber>
<act:telephoneNumber xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
<act:number>333-333-3333</act:number>
</act:telephoneNumber>
Anstatt die Namespaces im Abfrageprolog zu deklarieren, können Sie sie mithilfe WITH XMLNAMESPACESvon .
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes' AS act, 'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo' AS aci)
SELECT AdditionalContactInfo.query('
for $a in /aci:AdditionalContactInfo//act:telephoneNumber
order by $a/act:number[1] descending
return $a
') AS Result
FROM Person.Person
WHERE BusinessEntityID = 291;
Sie können auch nach Attributwert sortieren. Die folgende Abfrage ruft beispielsweise die neu erstellten <Location> Elemente ab, die die Attribute LocationID und LaborHours nach dem LaborHours-Attribut in absteigender Reihenfolge sortiert haben. Als Ergebnis dieses Vorgangs werden die Arbeitsplatzstandorte, die die größte Anzahl von Arbeitsstunden aufweisen, zuerst zurückgegeben.
SELECT Instructions.query('
declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
for $WC in /AWMI:root/AWMI:Location
order by $WC/@LaborHours descending
return
<Location>
{ $WC/@LocationID }
{ $WC/@LaborHours }
</Location>
') AS Result
FROM Production.ProductModel
WHERE ProductModelID = 7;
Das Ergebnis lautet wie folgt:
<Location LocationID="60" LaborHours="4"/>
<Location LocationID="50" LaborHours="3"/>
<Location LocationID="10" LaborHours="2.5"/>
<Location LocationID="20" LaborHours="1.75"/>
<Location LocationID="30" LaborHours="1"/>
<Location LocationID="45" LaborHours=".5"/>
In der folgenden Abfrage werden die Ergebnisse nach dem Elementnamen sortiert. Die Abfrage ruft die Spezifikationen eines bestimmten Produkts aus dem Produktkatalog ab. Die Spezifikationen sind die untergeordneten Elemente des <Specifications> Elements.
SELECT CatalogDescription.query('
declare namespace
pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
for $a in /pd:ProductDescription/pd:Specifications/*
order by local-name($a)
return $a
') AS Result
FROM Production.ProductModel
WHERE ProductModelID = 19;
Beachten Sie hinsichtlich der vorherigen Abfrage Folgendes:
Der
/p1:ProductDescription/p1:Specifications/*Ausdruck gibt untergeordnete Elemente von <Specifications>.Der
order by (local-name($a))-Ausdruck sortiert die Sequenz nach dem lokalen Namensanteil des Elementnamens.
Das Ergebnis lautet wie folgt:
<Color>Available in most colors</Color>
<Material>Aluminum Alloy</Material>
<ProductLine>Mountain bike</ProductLine>
<RiderExperience>Advanced to Professional riders</RiderExperience>
<Style>Unisex</Style>
Knoten, in denen der Sortierausdruck leer zurückgegeben wird, werden an den Beginn der Sequenz sortiert, wie das folgende Beispiel zeigt:
DECLARE @x AS XML;
SET @x = '<root>
<Person Name="A" />
<Person />
<Person Name="B" />
</root>
';
SELECT @x.query('
for $person in //Person
order by $person/@Name
return $person
');
Das Ergebnis lautet wie folgt:
<Person />
<Person Name="A" />
<Person Name="B" />
Sie können mehrere Sortierkriterien angeben, wie im folgenden Beispiel gezeigt wird. Die Abfrage in diesem Beispiel sortiert <Employee> Elemente zuerst nach Title und dann nach Administrator-Attributwerten.
DECLARE @x AS XML;
SET @x = '<root>
<Employee ID="10" Title="Teacher" Gender="M" />
<Employee ID="15" Title="Teacher" Gender="F" />
<Employee ID="5" Title="Teacher" Gender="M" />
<Employee ID="11" Title="Teacher" Gender="F" />
<Employee ID="8" Title="Administrator" Gender="M" />
<Employee ID="4" Title="Administrator" Gender="F" />
<Employee ID="3" Title="Teacher" Gender="F" />
<Employee ID="125" Title="Administrator" Gender="F" /></root>';
SELECT @x.query('for $e in /root/Employee
order by $e/@Title ascending, $e/@Gender descending
return
$e
');
Das Ergebnis lautet wie folgt:
<Employee ID="8" Title="Administrator" Gender="M" />
<Employee ID="4" Title="Administrator" Gender="F" />
<Employee ID="125" Title="Administrator" Gender="F" />
<Employee ID="10" Title="Teacher" Gender="M" />
<Employee ID="5" Title="Teacher" Gender="M" />
<Employee ID="11" Title="Teacher" Gender="F" />
<Employee ID="15" Title="Teacher" Gender="F" />
<Employee ID="3" Title="Teacher" Gender="F" />
Einschränkungen
Die folgenden Einschränkungen sind zu beachten:
Die Sortierausdrücke müssen homogen typisiert sein. Dies wird statisch überprüft.
Das Sortieren leerer Sequenzen kann nicht gesteuert werden.
Die am wenigsten leeren, größten und Sortierungsstichwörter
order bywerden nicht unterstützt.