Instrukcja FLWOR i iteracji (XQuery)
XQuery definiuje FLWOR składni iteracji.FLWOR jest akronim dla for, let, where, order by, a return.
Instrukcja FLWOR składa się z następujących elementów:
Jeden lub więcej dla klauzule, które powiązać jedną lub więcej zmiennych sterująca do wprowadzania sekwencji.
Sekwencji wejściowych mogą być inne wyrażenia XQuery, takich jak wyrażenia XPath.Są one sekwencji węzłów albo sekwencji niepodzielny wartości.Sekwencje niepodzielny wartość może być wykonane za pomocą literałów lub funkcje konstruktora.Nie wolno zbudowane węzłów XML jako danych wejściowych w SQL Server.
Opcjonalny let Klauzula. Tę klauzulę powoduje przypisanie wartości do danej zmiennej dla określonej iteracji.Przypisane wyrażenie może być wyrażeniem XQuery, takim jak wyrażenie XPath i mogą być zwracane sekwencja węzłów lub sekwencji niepodzielny wartości.Sekwencje niepodzielny wartość może być wykonane za pomocą literałów lub funkcji konstruktora.Nie wolno zbudowane węzłów XML jako danych wejściowych w SQL Server.
Zmienna sterująca.Ta zmienna może mieć potwierdzenia opcjonalne typu przy użyciu as słowo kluczowe.
Opcjonalny where Klauzula. Ta klauzula WHERE odnosi się predykat filtru na iteracji.
Opcjonalny order by Klauzula.
A return wyrażenie. Wyrażenie w return Klauzula konstruuje wynik FLWOR instrukcja.
Na przykład, poniższa kwerenda wykonuje iteracje, za pośrednictwem <Step> elementy w miejscu pierwszego produkcji 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)
')
To jest wynik:
Manu step 1 at Loc 1 Manu step 2 at Loc 1 Manu step 3 at Loc 1
Następująca kwerenda jest podobna do poprzedniego, z tą różnicą, że został on określony względem kolumna instrukcji, kolumna xml pisma, ProductModel tabela.Kwerendy iterację przez wszystkie etapy produkcji <step> elementy w pierwszej lokalizacji środka pracy 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
Pierwszy przycisk jest przyciskiem domyślnym.
The $Step is the iterator variable.
The ścieżka wyrażenie, //AWMI:root/AWMI:Location[1]/AWMI:step, generates the input sequence. Ta kolejność jest sekwencja <step> elementy podrzędne węzła element pierwszy <Location> węzeł elementu.
Opcjonalna klauzula predykatu, where, nie jest używany.
The return wyrażenie returns a ciąg value from the <step> element.
The ciąg funkcja (XQuery) is used to retrieve the ciąg value of the <step> node.
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. ....
Poniżej przedstawiono przykłady dodatkowe sekwencje danych 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 sekwencji nie są dozwolone. W szczególności sekwencji, zawierające wartości niepodzielny i węzły nie są dozwolone.
Iteracja jest często używane w połączeniu z Budowa XML składni Przekształcanie formaty XML, jak pokazano na następne kwerendy.
W przykładowej bazy danych AdventureWorks instrukcje produkcji są przechowywane w Instrukcje kolumnaProduction.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 nową XML, który ma <Location> Zwracane elementy z atrybutami lokalizacji środka pracy 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
Pierwszy przycisk jest przyciskiem domyślnym.
Instrukcja FLWOR pobiera sekwencji <Location> elementy dla określonego produktu.
The data funkcja (XQuery) is used to wyodrębnić the value of each atrybut so they will be added to the resulting XML as text nodes instead of as attributes.
wyrażenie w klauzula RETURN konstrukcji 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>
...
Za pomocą umożliwiają klauzula
Można użyć let Klauzula do wyrażenia powtarzające się nazwy, które mogą odwoływać się do odwołując się do zmiennej. Należy zauważyć, że programu SQL Server 2008, wyrażenie przypisywane do let Zmienna zostanie wstawiona do kwerendy, zawsze odwołuje się do zmiennej w kwerendzie. Oznacza to, że instrukcja nie zostaną wykonane tylko raz, ale tyle razy, ile wyrażenie pobiera odwołuje się do.
W bazie danych AdventureWorks instrukcje produkcji zawierają informacje o narzędzia niezbędne i lokalizacji używanych narzędzi.Następujące kwerendy zastosowań let Klauzula, aby wyświetlić listę narzędzi niezbędnych do utworzenia modelu produkcji, jak również lokalizacji, gdzie jest potrzebny 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
Za pomocą gdzie klauzula
Można użyć where Klauzula do filtrowania wyniki interation. Jest to zilustrowane w następnym przykładzie przy użyciu przykładowej bazy danych AdventureWorks.
W produkcji roweru procesu produkcyjnego przechodzi przez serię gniazda roboczego lokalizacji.Każdej lokalizacji gniazda roboczego definiuje sekwencję kroków produkcji.Następująca kwerenda pobiera tylko te pracy gniazda lokalizacje, które produkowanych modeli rowerów i mają mniej niż trzy kroki produkcji.Oznacza to mają mniej niż trzech <step> elementy.
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
Należy uwzględnić następujące metody w poprzedniej kwerendy:
The where keyword uses the count() funkcja to count the number of <step> podrzędność elements in each work center location.
The return wyrażenie constructs the XML that you want from the wyniki of the iteration.
To jest wynik:
<Location LocationID="30"/>
Wynik wyrażenie w where Klauzula jest konwertowany na logiczny właściwości za pomocą następujących reguł w podanej kolejności. Są to taki sam, jak zasady predykaty w wyrażeniach ścieżka z tą różnicą, że liczby całkowite są niedozwolone:
Jeśli where wyrażenie zwraca pusty sekwencję, jego skuteczne logiczny ma wartość FAŁSZ.
Jeśli where wyrażenie zwraca jedną wartość typu logiczny prostego, jest to skuteczne wartość typu logiczny.
Jeśli where wyrażenie zwraca sekwencja, która zawiera przynajmniej jeden węzeł, efektywne logiczny jest TRUE.
W przeciwnym razie niemożliwe błąd statyczne.
Wiele zmiennych wiązanie w FLWOR
Można utworzyć pojedyncze wyrażenie FLWOR, która wiąże wielu zmiennych do wprowadzania sekwencji.W następującym przykładzie określono kwerendy przed zmienną bez typu xml.Wyrażenie FLOWR zwraca pierwszy <Step> element podrzędność w każdym <Location> element.
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)
')
Należy uwzględnić następujące z poprzedniej kwerendy:
The for wyrażenie defines $Loc and $FirstStep variables.
The two expressions, /ManuInstructions/Location and $FirstStep in $Loc/Step[1], are correlated in that the values of $FirstStep depend on the values of $Loc.
Wyrażenie skojarzone z $Loc generuje sekwencji <Location> elementy. Dla każdego <Location> element, $FirstStep generuje sekwencja jednego <Step> element jest pojedyncza.
$Loc jest określony w wyrażenie skojarzone z $FirstStep Zmienna.
To jest wynik:
Manu step 1 at Loc 1
Manu step 1 at Loc 2
Następująca kwerenda jest podobna, z tą różnicą, że został on określony względem kolumny instrukcji, wpisane XML Kolumna ProductModel tabela.Budowa XML (XQuery) jest używany do generowania pliku XML, który ma.
SELECT Instructions.query('
declare default 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
Należy uwzględnić następujące metody w poprzedniej kwerendy:
The for klauzula defines two variables, $WC and $S. Wyrażenie skojarzone z $WC generuje sekwencji gniazda roboczego lokalizacje w produkcji roweru modelu produktu. Wyrażenie ścieżka przypisane do $S Zmienna generuje sekwencji kroków dla każdej sekwencji lokalizacji środka pracy w $WC.
Instrukcja return konstrukcji XML, który ma <Step> element zawierający na etapie produkcji oraz LocationID jako atrybut.
The declare default element namespace is used in the XQuery prolog so that all the namespace declarations in the resulting XML appear at the top-poziom element.W ten sposób wynik był bardziej czytelny.Aby uzyskać więcej informacji na temat obszarów nazw domyślnych zobacz Obsługa obszarów 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 klauzula
W XQuery sortowanie jest wykonywane przy użyciu order by Klauzula w wyrażeniu FLWOR. 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 może skutkować pojedyncza sekwencji z jednego element.Domyślnie sortowanie jest wykonywane w kolejności rosnącej.Opcjonalnie można określić kolejności rosnącej lub malejącej dla każdego wyrażenie sortowania.
Uwaga
Porównanie sortowanie na wykonywane przez implementację XQuery w wartości ciąg SQL Server zawsze przeprowadzane przy użyciu binarne sortowanie codepoint Unicode.
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.Contact
WHERE ContactID=3
Należy zauważyć, że Atomizacja (XQuery) procesu pobiera wartość niepodzielny elementów <number> przed przekazaniem go do order by. Wyrażenie można napisać za pomocą Data() funkcja, ale nie jest wymagane.
order by data($a/act:number[1]) descending
To jest wynik:
<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 deklarowanie obszarów nazw w prologu kwerendy, można je zadeklarować przy użyciu XMLNAMESPACES WITH.
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.Contact
WHERE ContactID=3
Można też sortować według wartości atrybut.Na przykład poniższa kwerenda pobiera nowo utworzony <Location> elementy, które mają atrybut LocationID i LaborHours posortowane wg atrybutu LaborHours w kolejności malejącej. W rezultacie lokalizacji środka pracy, które mają robocizny maksymalną liczbę godzin 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
To jest wynik:
<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 konkretnego produktu z katalogu produktów.Specyfikacje są podrzędne wobec <Specifications> element.
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
Pierwszy przycisk jest przyciskiem domyślnym.
The /p1:ProductDescription/p1:Specifications/* wyrażenie returns element children of <Specifications>.
The order by (local-name($a)) wyrażenie sorts the sequence by the local part of the element name.
To jest wynik:
<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órym zamawiania wyrażenie zwraca pusty są sortowane na początku sekwencji, jak pokazano w poniższym 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
')
To jest wynik:
<Person />
<Person Name="A" />
<Person Name="B" />
Można określić wiele kryteriów sortowania, jak pokazano w poniższym przykładzie.Sortuje kwerendy, w tym przykładzie <Employee> elementy najpierw według tytułu, a następnie przez administratora atrybut wartości.
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
')
To jest wynik:
<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" />
defaultButton
Ograniczenia są następujące:
Wyrażenia sortowania muszą być homogeniczne pod względem uwzględniania typów.Jest to sprawdzane statycznie.
Nie można sterować puste sekwencji sortowania.
Pusty co najmniej, kluczowych największe jest pusta i sortowanie na order by nie są obsługiwane