Sequenzausdrücke (XQuery)
SQL Server unterstützt die XQuery-Operatoren, die zum Konstruieren, Filtern und Kombinieren einer Sequenz aus Items verwendet werden. Ein Item kann entweder ein atomarer Wert oder ein Knoten sein.
Konstruieren von Sequenzen
Mithilfe des Kommaoperators können Sie eine Sequenz konstruieren, die Items zu einer einzigen Sequenz verkettet.
Eine Sequenz kann doppelte Werte enthalten. Geschachtelte Sequenzen, also eine Sequenz innerhalb einer Sequenz, werden reduziert. So wird z. B. die Sequenz (1, 2, (3, 4, (5))) zu (1, 2, 3, 4, 5). Es folgen Beispiele für das Konstruieren von Sequenzen.
Beispiel A
Die folgende Abfrage gibt eine Sequenz aus fünf atomaren Werten zurück:
declare @x xml
set @x=''
select @x.query('(1,2,3,4,5)')
go
-- result 1 2 3 4 5
Die folgende Abfrage gibt eine Sequenz aus zwei Knoten zurück:
-- sequence of 2 nodes
declare @x xml
set @x=''
select @x.query('(<a/>, <b/>)')
go
-- result
<a />
<b />
Die folgende Abfrage gibt einen Fehler zurück, weil Sie eine Sequenz aus atomaren Werten und Knoten konstruieren. Dies ist eine heterogene Sequenz, die nicht unterstützt wird.
declare @x xml
set @x=''
select @x.query('(1, 2, <a/>, <b/>)')
go
Beispiel B
Die folgende Abfrage konstruiert eine Sequenz aus atomaren Werten, indem vier Sequenzen mit unterschiedlicher Länge zu einer einzigen Sequenz kombiniert werden.
declare @x xml
set @x=''
select @x.query('(1,2),10,(),(4, 5, 6)')
go
-- result = 1 2 10 4 5 6
Sie können die Sequenz mithilfe von FLOWR und ORDER BY sortieren:
declare @x xml
set @x=''
select @x.query('for $i in ((1,2),10,(),(4, 5, 6))
order by $i
return $i')
go
Mithilfe der Funktion fn:count() können Sie die in der Sequenz enthaltenen Items zählen.
declare @x xml
set @x=''
select @x.query('count( (1,2,3,(),4) )')
go
-- result = 4
Beispiel C
Die folgende Abfrage ist für die AdditionalContactInfo-Spalte des xml-Typs in der Contact-Tabelle angegeben. Diese Spalte speichert zusätzliche Kontaktinformationen, z. B. eine oder mehrere zusätzliche Telefonnummern, Pagernummern und Adressen. <telephoneNumber>-, <pager>- und andere Knoten können an beliebiger Position innerhalb des Dokuments erscheinen. Die Abfrage konstruiert eine Sequenz, die alle untergeordneten <telephoneNumber>-Elemente des Kontextknotens enthält, gefolgt von den untergeordneten Elementen des <pager>-Elements. Beachten Sie die Verwendung des Kommasequenzoperators im zurückgegebenen Ausdruck ($a//act:telephoneNumber, $a//act:pager).
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
return ($a//act:telephoneNumber, $a//act:pager)
') As Result
FROM Person.Contact
WHERE ContactID=3
Dies ist das Ergebnis:
<act:telephoneNumber xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
<act:number>333-333-3333</act:number>
</act:telephoneNumber>
<act:telephoneNumber xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
<act:number>333-333-3334</act:number>
</act:telephoneNumber>
<act:pager xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
<act:number>999-555-1244</act:number>
<act:SpecialInstructions>
Page only in case of emergencies.
</act:SpecialInstructions>
</act:pager>
Filtern von Sequenzen
Sie können die durch einen Ausdruck zurückgegebene Sequenz filtern, indem Sie dem Ausdruck ein Prädikat hinzufügen. Weitere Informationen finden Sie unter Pfadausdrücke (XQuery). Die folgende Abfrage gibt z. B. eine Sequenz aus drei <a>-Elementknoten zurück:
declare @x xml
set @x = '<root>
<a attrA="1">111</a>
<a></a>
<a></a>
</root>'
SELECT @x.query('/root/a')
Dies ist das Ergebnis:
<a attrA="1">111</a>
<a />
<a />
Um nur <a>-Elemente abzurufen, die das Attribut attrA haben, können Sie im Prädikat einen Filter angeben. Die resultierende Sequenz verfügt nur über ein einzelnes <a>-Element.
declare @x xml
set @x = '<root>
<a attrA="1">111</a>
<a></a>
<a></a>
</root>'
SELECT @x.query('/root/a[@attrA]')
Dies ist das Ergebnis:
<a attrA="1">111</a>
Weitere Informationen zum Angeben von Prädikaten in einem Pfadausdruck finden Sie unter Angeben von Prädikaten in einem Pfadausdrucksschritt.
Das folgende Beispiel erstellt einen Sequenzausdruck aus Teilbäumen und wendet dann einen Filter auf die Sequenz an.
declare @x xml
set @x = '
<a>
<c>C under a</c>
</a>
<b>
<c>C under b</c>
</b>
<c>top level c</c>
<d></d>
'
Der Ausdruck in (/a, /b) konstruiert eine Sequenz mit den Teilbäumen /a und /b, und aus der resultierenden Sequenz filtert der Ausdruck das Element <c>.
SELECT @x.query('
(/a, /b)/c
')
Dies ist das Ergebnis:
<c>C under a</c>
<c>C under b</c>
Das folgende Beispiel wendet einen Prädikatfilter an. Der Ausdruck findet die Elemente <a> und <b>, die das Element <c> enthalten.
declare @x xml
set @x = '
<a>
<c>C under a</c>
</a>
<b>
<c>C under b</c>
</b>
<c>top level c</c>
<d></d>
'
SELECT @x.query('
(/a, /b)[c]
')
Dies ist das Ergebnis:
<a>
<c>C under a</c>
</a>
<b>
<c>C under b</c>
</b>
Implementierungseinschränkungen
Es gelten folgende Einschränkungen:
Der XQuery-range-Ausdruck wird nicht unterstützt.
Die Sequenzen müssen homogen sein. Das heißt, dass alle Items in einer Sequenz entweder Knoten oder atomare Werte sein müssen. Dies wird statisch überprüft.
Das Kombinieren von Sequenzen mit dem union-, intersect- oder except-Operator wird nicht unterstützt.