Instrukcja FLWOR i iteracji (XQuery)
XQuery definiuje składni FLWOR iteracji.FLWOR is the acronym for for, let, where, order by, and return.
Instrukcja FLWOR składa się z następujących części:
Jeden lub więcej dla klauzul, które powiązać jedną lub więcej zmiennych sterująca do wprowadzania sekwencji.
Sekwencji wejściowych może być inne wyrażenia XQuery, takich jak wyrażenia XPath.Są one sekwencji węzłów albo sekwencji niepodzielny wartości.Sekwencje Atomowej wartość może zostać skonstruowana przy użyciu funkcji konstruktora lub literałów.Skonstruowane węzłów XML nie są dozwolone w sekwencji jako nakłady w SQL Server.
Opcjonalny let klauzula.To klauzula przypisuje wartość danej zmiennej dla określonej iteracji.Przypisane wyrażenie wyrażenie XQuery, takim jak wyrażenie XPath i może zwracać sekwencja węzłów lub sekwencji niepodzielny wartości.Sekwencje Atomowej wartość można skonstruowany przy użyciu funkcji konstruktora lub literałów.Skonstruowane węzłów XML nie są dozwolone w sekwencji jako nakłady w SQL Server.
Zmienna sterująca.Ta zmienna może mieć potwierdzenia opcjonalne typu za pomocą as słów kluczowych.
Opcjonalny where klauzula.To klauzula dotyczy predykat filtru na iterację.
Opcjonalny order by klauzula.
A return wyrażenie.Wyrażenie w return klauzula konstrukcje wynik instrukcja FLWOR.
Na przykład, poniższa kwerenda wykonuje iterację przez <Step> elementów w pierwszej lokalizacji wytwarzania i zwraca wartość ciąg <Step> węzły:
declare @x 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)
')
Jest to wynikiem:
Manu step 1 at Loc 1 Manu step 2 at Loc 1 Manu step 3 at Loc 1
Następująca kwerenda jest podobny do poprzedniego, chyba że określono wobec kolumna instrukcje, kolumną maszynowy xml w tabela ProductModel.Kwerenda wykonuje iterację przez wszystkie etapy produkcji, <step> elementów w miejscu pierwszej pracy Centrum dla określonego produktu.
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
Poniższe z poprzedniej kwerendy:
$Step Jest zmienna sterująca.
Wyrażenie ścieżka, //AWMI:root/AWMI:Location[1]/AWMI:step, generuje sekwencji wejściowych.Ta sekwencja jest z <step> dzieci węzeł element pierwszego <Location> węzeł elementu.
Opcjonalna klauzula predykatu where, nie jest używany.
return Wyrażenie zwraca wartość ciąg z <step> elementu.
Ciąg funkcja (XQuery) jest używana do pobierania wartości ciągu <step> węzła.
Jest to wynik częściowy:
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. ....
Oto przykłady dodatkowe sekwencji wejściowych, które są dozwolone:
declare @x xml
set @x=''
SELECT @x.query('
for $a in (1, 2, 3)
return $a')
-- result = 1 2 3
declare @x 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 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
W SQL Server, heterogenicznych sekwencje są niedozwolone.W szczególności sekwencji zawierające mieszankę niepodzielny wartości i węzły nie są dozwolone.
Iteracja jest często używana razem z Konstrukcji XML składni XML Przekształcanie formaty, jak pokazano w następnej kwerendzie.
W AdventureWorks2008R2 Przykładowa baza danych, instrukcje wytwarzania, przechowywane w instrukcje kolumna Production.ProductModel tabela ma następującą postać:
<Location LocationID="10" LaborHours="1.2"
SetupHours=".2" MachineHours=".1">
<step>describes 1st manu step</step>
<step>describes 2nd manu step</step>
...
</Location>
...
Poniższa kwerenda tworzy nowy plik XML, który ma <Location> elementów z pracami Centrum atrybuty lokalizacji zwracane jako elementy podrzędność:
<Location>
<LocationID>10</LocationID>
<LaborHours>1.2</LaborHours>
<SetupHours>.2</SteupHours>
<MachineHours>.1</MachineHours>
</Location>
...
To jest kwerenda:
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
Poniższe z poprzedniej kwerendy:
Instrukcja FLWOR pobiera sekwencji <Location> elementów dla określonego produktu.
funkcja danych (XQuery) wyodrębnić wartości każdego atrybut, dzięki czemu zostaną one dodane do wynikowego pliku XML jako węzły tekstu zamiast jako atrybuty.
wyrażenie w klauzula zwrotu konstrukcje XML, który ma.
Jest to wynik częściowy:
<Location>
<LocationID>10</LocationID>
<LaborHours>2.5</LaborHours>
<SetupHours>0.5</SetupHours>
<MachineHours>3</MachineHours>
</Location>
<Location>
...
<Location>
...
Dzięki użyciu klauzuli
Można użyć let klauzula nazwę powtarzające się wyrażenia, których może dotyczyć odwołując się do zmiennej.Należy zauważyć, że w programie SQL Server 2008 wyrażenie przypisany do let zmiennej zostanie wstawiona do kwerendy co czas odwołuje się do zmiennej w kwerendzie.Oznacza to, że instrukcja nie zostanie wykonany tylko raz, ale tyle razy, ile wyrażenie pobiera odwołanie.
W AdventureWorks2008R2 bazy danych, instrukcje produkcji zawierają informacje wymagane narzędzia i lokalizacji, w których są używane narzędzia.Następujące kwerendy używa let klauzula listę narzędzie wymagane do utworzenia modelu produkcji, jak również miejsc, gdzie potrzeby każdego narzędzie.
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
Gdzie używając klauzuli
Można użyć where klauzula filtrować wyniki interation.Jest to zademonstrowane w następnym przykładzie przy użyciu AdventureWorks2008R2 przykładowej bazy danych.
Produkcji roweru proces produkcji przechodzi przez serię prac Centrum lokalizacje.Każdej lokalizacji Centrum pracy określa sekwencję kroków produkcji.Następująca kwerenda pobiera tylko pracy Centrum lokalizacji, w których produkcja modeli rowerów i mają mniej niż trzy etapy wytwarzania.Oznacza to, że mają one mniej niż trzech <step> elementów.
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
Poniższe w poprzedniej kwerendy:
where Wykorzystuje słowo kluczowe count() funkcja zliczania <step> elementów podrzędność w przypadku każdej pracy Centrum lokalizacji.
return wyrażenie konstruuje XML, którego wyniki iteracji.
Jest to wynikiem:
<Location LocationID="30"/>
Wynik wyrażenie w where klauzula jest konwertowany na wartość logiczna przy użyciu następujących reguł w określonej kolejności.Są to taki sam, jak zasady predykaty w wyrażeniach ścieżka, chyba, że całkowite nie są dozwolone:
Jeśli where wyrażenie zwraca pusty sekwencji, jest jej skutecznego wartość logiczna FAŁSZ.
Jeśli where wyrażenie zwraca jedną wartość typu wartość logiczna prostego, że wartość jest skuteczne wartość logiczna.
Jeśli where wyrażenie zwraca sekwencji, który zawiera co najmniej jeden węzeł, jest skuteczne wartość logiczna PRAWDA.
W przeciwnym razie podnosi błąd statyczne.
Wiele powiązanie zmiennej w FLWOR
Może mieć pojedyncze wyrażenie FLWOR, która wiąże się wiele zmiennych do wprowadzania sekwencji.W następującym przykładzie określono kwerendy przeciwko zmiennej bez typu xml.Wyrażenie FLOWR zwraca pierwszy <Step> element podrzędność w każdym <Location> elementu.
declare @x 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)
')
Poniższe z poprzedniej kwerendy:
for Definiuje wyrażenie $Loc i $FirstStep zmiennych.
two Wyrażeń, /ManuInstructions/Location i $FirstStep in $Loc/Step[1], są skorelowane w tym wartości $FirstStep zależą od wartości $Loc.
Wyrażenie skojarzone z $Loc generuje sekwencji <Location> elementów.Dla każdego <Location> element, $FirstStep generuje sekwencji jednej <Step> element, singleton.
$Locokreślona w wyrażenie związane z $FirstStep zmiennej.
Jest to wynikiem:
Manu step 1 at Loc 1
Manu step 1 at Loc 2
Następująca kwerenda jest podobna, chyba że określono wobec kolumna instrukcje, wpisany xml kolumna, z ProductModel tabela.Budowa XML (XQuery) jest używany do generowania XML, który ma.
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
Poniższe w poprzedniej kwerendy:
for klauzula definiuje dwie zmienne $WC i $S.Wyrażenie skojarzone z $WC generuje sekwencji pracy Centrum lokalizacji produkcji modelu produktu rowerów.Wyrażenie ścieżka przypisane do $S zmiennej generuje sekwencji etapów dla każdej sekwencji lokalizacji pracy Centrum w $WC.
Instrukcja return konstrukcje XML, który ma <Step> element, który zawiera etap wytwarzania i LocationID jako atrybut.
Zadeklarować domyślny obszar nazw elementu jest używana w prologu XQuery, tak aby wszystkie deklaracje obszaru nazw XML wynikowy pojawiają się na element najwyższego poziom.Dzięki temu wynik był bardziej czytelny.Aby uzyskać więcej informacji o domyślnych nazw, zobacz Obsługa nazw w XQuery.
Jest to wynik częściowy:
<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>
...
W kolejności według klauzuli
W XQuery sortowanie jest wykonywane za pomocą order by klauzula w FLWOR wyrażenie.Wyrażenia sortowania przekazany do order by klauzula musi zwracać wartości, których typy są prawidłowe dla gt operator.Każde wyrażenie sortowania musi skutkować singleton sekwencji z jednego element.Domyślnie sortowanie jest wykonywane w kolejności rosnącej.Opcjonalnie można określić porządku rosnącym lub malejącym, dla każdego wyrażenie sortowania.
Ostrzeżenie
Sortowanie porównania wartości ciąg wykonywane przez implementację XQuery w SQL Server są zawsze wykonywane za pomocą binarne Unicode punktów kodowych znaków dwuskładnikowych sortowania.
Następująca kwerenda pobiera wszystkie numery telefonów dla określonego nabywcy z kolumna AdditionalContactInfo.Wyniki są sortowane według numeru telefonu.
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 = 293
Należy zauważyć, że Atomizacja (XQuery) proces pobiera wartość niepodzielny <number> elementy przed przekazaniem go do order by.Można napisać wyrażenie przy użyciu data() funkcja, ale nie jest wymagane.
order by data($a/act:number[1]) descending
Jest to wynikiem:
<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>
Zamiast deklarowania obszarów nazw w prologu kwerendy, można zadeklarować je korzystając Z XMLNAMESPACES.
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 = 293;
Można także sortować według wartości atrybut.Na przykład, poniższa kwerenda pobiera nowo utworzone <Location> elementów, które mają atrybutów LocationID i LaborHours, posortowane według atrybut LaborHours w kolejności malejącej.W wyniku centrach pracy, których godzin robocizny maksymalną zwracane są najpierw.
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
Jest to wynikiem:
<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"/>
W następującej kwerendzie wyniki są sortowane według nazwy elementu.Kwerenda pobiera specyfikacje produktu z katalogu produktów.Specyfikacje są dzieci <Specifications> elementu.
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
Poniższe z poprzedniej kwerendy:
/p1:ProductDescription/p1:Specifications/* Wyrażenie zwraca elementy podrzędne elementu <Specifications>.
order by (local-name($a)) Wyrażenie sortuje sekwencji przez lokalną część nazwy elementu.
Jest to wynikiem:
<Color>Available in most colors</Color>
<Material>Almuminum Alloy</Material>
<ProductLine>Mountain bike</ProductLine>
<RiderExperience>Advanced to Professional riders</RiderExperience>
<Style>Unisex</Style>
Węzły, w których zamawiania wyrażenie zwraca pusty są sortowane na początku sekwencji, jak pokazano w następującym przykładzie:
declare @x 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
')
Jest to wynikiem:
<Person />
<Person Name="A" />
<Person Name="B" />
Można określić wiele kryteriów sortowania, jak pokazano w następującym przykładzie.W tym przykładzie kwerenda posortuje <Employee> elementów najpierw według tytułu, a następnie według wartości atrybut administratora.
declare @x 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
')
Jest to wynikiem:
<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" />
Ograniczenia wdrażania
Są następujące ograniczenia:
Wyrażenia sortowania musi być wpisana jednorodnie.Statycznie jest sprawdzany.
Nie można sterować pusty sekwencji sortowania.
Pusty najmniej kluczowe pustych największe i sortowanie na order by nie są obsługiwane