Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Berlaku untuk:SQL Server
XQuery mendefinisikan sintaks iterasi FLWOR. FLWOR adalah akronim dari for, , letwhere, order by, dan return.
Pernyataan FLWOR terdiri dari bagian-bagian berikut:
Satu atau beberapa
FORklausa yang mengikat satu atau beberapa variabel iterator ke urutan input.Urutan input dapat berupa ekspresi XQuery lainnya seperti ekspresi XPath. Keduanya adalah urutan simpul atau urutan nilai atomik. Urutan nilai atom dapat dibangun menggunakan literal atau fungsi konstruktor. Simpul XML yang dibuat tidak diizinkan sebagai urutan input di SQL Server.
Klausa opsional
let. Klausa ini menetapkan nilai ke variabel yang diberikan untuk iterasi tertentu. Ekspresi yang ditetapkan dapat berupa ekspresi XQuery seperti ekspresi XPath, dan dapat mengembalikan urutan simpul atau urutan nilai atomik. Urutan nilai atom dapat dibangun dengan menggunakan fungsi literal atau konstruktor. Simpul XML yang dibuat tidak diizinkan sebagai urutan input di SQL Server.Variabel iterator. Variabel ini dapat memiliki pernyataan jenis opsional dengan menggunakan
askata kunci.Klausa opsional
where. Klausa ini menerapkan predikat filter pada iterasi.Klausa opsional
order by.Ekspresi
return. Ekspresi dalamreturnklausul membangun hasil pernyataan FLWOR.
Misalnya, kueri <Step> berikut mengulangi elemen di lokasi manufaktur pertama dan mengembalikan nilai string simpul:<Step>
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)
');
Berikut hasilnya:
Manu step 1 at Loc 1 Manu step 2 at Loc 1 Manu step 3 at Loc 1
Kueri berikut ini mirip dengan yang sebelumnya, kecuali yang ditentukan terhadap kolom Instruksi, kolom xml yang diketik, dari tabel ProductModel. Kueri berulang di semua langkah manufaktur, <step> elemen, di lokasi pusat kerja pertama untuk produk tertentu.
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;
Perhatikan hal berikut ini dari kueri sebelumnya:
$Stepadalah variabel iterator.Ekspresi jalur,
//AWMI:root/AWMI:Location[1]/AWMI:step, menghasilkan urutan input. Urutan ini adalah urutan turunan <step> simpul elemen dari node elemen pertama.<Location>Klausa predikat opsional,
where, tidak digunakan.Ekspresi
returnmengembalikan nilai string dari <step> elemen .
Fungsi string (XQuery) digunakan untuk mengambil nilai string simpul<step>.
Berikut hasil parsialnya:
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. ....
Ini adalah contoh urutan input lain yang diizinkan:
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
Di SQL Server, urutan heterogen tidak diizinkan. Secara khusus, urutan yang berisi campuran nilai atom dan simpul tidak diizinkan.
Iterasi sering digunakan bersama dengan sintaks konstruksi XML (XQuery) dalam mengubah format XML, seperti yang ditunjukkan pada kueri berikutnya.
Dalam database sampel AdventureWorks, instruksi manufaktur yang disimpan di Instructions kolom Production.ProductModel tabel memiliki formulir berikut:
<Location LocationID="10" LaborHours="1.2"
SetupHours=".2" MachineHours=".1">
<step>describes 1st manu step</step>
<step>describes 2nd manu step</step>
...
</Location>
...
Kueri berikut membuat XML baru yang memiliki <Location> elemen dengan atribut lokasi pusat kerja yang dikembalikan sebagai elemen turunan:
<Location>
<LocationID>10</LocationID>
<LaborHours>1.2</LaborHours>
<SetupHours>.2</SetupHours>
<MachineHours>.1</MachineHours>
</Location>
...
Berikut kuerinya:
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;
Perhatikan pertimbangan berikut dari kueri sebelumnya:
Pernyataan FLWOR mengambil urutan <
Location> elemen untuk produk tertentu.Fungsi data (XQuery) digunakan untuk mengekstrak nilai setiap atribut sehingga ditambahkan ke XML yang dihasilkan sebagai simpul teks alih-alih sebagai atribut.
Ekspresi dalam
RETURNklausa membuat XML yang Anda inginkan.
Ini adalah hasil parsial:
<Location>
<LocationID>10</LocationID>
<LaborHours>2.5</LaborHours>
<SetupHours>0.5</SetupHours>
<MachineHours>3</MachineHours>
</Location>
<Location>
...
<Location>
...
let Gunakan klausa
Anda dapat menggunakan let klausul untuk memberi nama ekspresi berulang yang dapat Anda rujuk dengan merujuk ke variabel . Ekspresi yang let ditetapkan ke variabel dimasukkan ke dalam kueri setiap kali variabel direferensikan dalam kueri. Ini berarti bahwa pernyataan dijalankan sebanyak ekspresi direferensikan.
AdventureWorks2025 Dalam database, instruksi manufaktur berisi informasi tentang alat yang diperlukan dan lokasi tempat alat digunakan. Kueri berikut menggunakan klausul let untuk mencantumkan alat yang diperlukan untuk membangun model produksi, dan lokasi di mana setiap alat diperlukan.
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;
where Gunakan klausa
Anda dapat menggunakan where klausa untuk memfilter hasil iterasi. Ini diilustrasikan dalam contoh berikutnya ini.
Dalam pembuatan sepeda, proses manufaktur melalui serangkaian lokasi pusat kerja. Setiap lokasi pusat kerja menentukan urutan langkah-langkah manufaktur. Kueri berikut hanya mengambil lokasi pusat kerja yang memproduksi model sepeda dan memiliki kurang dari tiga langkah manufaktur. Artinya, mereka memiliki kurang dari tiga <step> elemen.
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;
Perhatikan hal berikut ini di kueri sebelumnya:
Kata
wherekunci menggunakancount()fungsi untuk menghitung jumlah <step> elemen anak di setiap lokasi pusat kerja.returnEkspresi membuat XML yang Anda inginkan dari hasil iterasi.
Berikut hasilnya:
<Location LocationID="30"/>
Hasil ekspresi dalam klausa dikonversi where ke nilai Boolean dengan menggunakan aturan berikut, dalam urutan yang ditentukan. Ini sama dengan aturan untuk predikat dalam ekspresi jalur, kecuali bilangan bulat tidak diizinkan:
whereJika ekspresi mengembalikan urutan kosong, nilai Boolean yang efektif adalah False.whereJika ekspresi mengembalikan satu nilai jenis Boolean sederhana, nilai tersebut adalah nilai Boolean yang efektif.whereJika ekspresi mengembalikan urutan yang berisi setidaknya satu simpul, nilai Boolean yang efektif adalah True.Jika tidak, itu menimbulkan kesalahan statis.
Beberapa pengikatan variabel dalam FLWOR
Anda dapat memiliki satu ekspresi FLWOR yang mengikat beberapa variabel ke urutan input. Dalam contoh berikut, kueri ditentukan terhadap variabel xml yang tidak dititip. Ekspresi FLOWR mengembalikan turunan elemen pertama <Step> di setiap <Location> elemen.
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)
');
Perhatikan hal berikut ini dari kueri sebelumnya:
forEkspresi mendefinisikan$Locdan $FirstStepvariabel.Ekspresi
two,/ManuInstructions/Locationdan$FirstStep in $Loc/Step[1], berkorelasi dalam nilai$FirstStepbergantung pada nilai$Loc.Ekspresi yang terkait dengan
$Locmenghasilkan urutan <Location> elemen. Untuk setiap <Location> elemen,$FirstStepmenghasilkan urutan satu <Step> elemen, satuton.$Locditentukan dalam ekspresi yang terkait dengan$FirstStepvariabel.
Berikut hasilnya:
Manu step 1 at Loc 1
Manu step 1 at Loc 2
Kueri berikut ini serupa, kecuali bahwa kueri tersebut ditentukan terhadap kolom Instruksi, kolom xml yang diketik, dari ProductModel tabel.
Konstruksi XML (XQuery) digunakan untuk menghasilkan XML yang Anda inginkan.
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;
Perhatikan hal berikut ini di kueri sebelumnya:
Klausa
formendefinisikan dua variabel,$WCdan$S. Ekspresi yang terkait dengan$WCmenghasilkan urutan lokasi pusat kerja dalam pembuatan model produk sepeda. Ekspresi jalur yang$Sditetapkan ke variabel menghasilkan urutan langkah-langkah untuk setiap urutan lokasi pusat kerja di$WC.Pernyataan pengembalian membangun XML yang memiliki <
Step> elemen yang berisi langkah manufaktur danLocationIDsebagai atributnya.Namespace elemen default deklarasikan digunakan dalam prolog XQuery sehingga semua deklarasi namespace dalam XML yang dihasilkan muncul di elemen tingkat atas. Ini membuat hasilnya lebih mudah dibaca. Untuk informasi selengkapnya tentang namespace default, lihat Menangani Namespace di XQuery.
Berikut hasil parsialnya:
<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>
...
order by Gunakan klausa
Pengurutan dalam XQuery dilakukan dengan menggunakan order by klausa dalam ekspresi FLWOR. Ekspresi pengurutan yang diteruskan ke order by klausul harus mengembalikan nilai yang jenisnya valid untuk gt operator. Setiap ekspresi pengurutan harus menghasilkan satuton urutan dengan satu item. Secara default, pengurutan dilakukan dalam urutan naik. Anda dapat secara opsional menentukan urutan naik atau menurun untuk setiap ekspresi pengurutan.
Catatan
Pengurutan perbandingan pada nilai string yang dilakukan oleh implementasi XQuery di SQL Server selalu dilakukan dengan menggunakan kolase titik kode Unicode biner.
Kueri berikut mengambil semua nomor telepon untuk pelanggan tertentu dari kolom AdditionalContactInfo. Hasilnya diurutkan menurut nomor telepon.
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;
Proses Atomisasi (XQuery) mengambil nilai atom dari <number> elemen sebelum meneruskannya ke .order by Anda dapat menulis ekspresi dengan menggunakan data() fungsi , tetapi itu tidak diperlukan.
order by data($a/act:number[1]) descending
Berikut hasilnya:
<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>
Alih-alih mendeklarasikan namespace dalam prolog kueri, Anda dapat mendeklarasikannya dengan menggunakan WITH 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 = 291;
Anda juga dapat mengurutkan berdasarkan nilai atribut. Misalnya, kueri berikut mengambil elemen yang baru dibuat <Location> yang memiliki atribut LocationID dan LaborHours yang diurutkan menurut atribut LaborHours dalam urutan menurun. Akibatnya, lokasi pusat kerja yang memiliki jam kerja maksimum dikembalikan terlebih dahulu.
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;
Berikut hasilnya:
<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"/>
Dalam kueri berikut, hasilnya diurutkan menurut nama elemen. Kueri mengambil spesifikasi produk tertentu dari katalog produk. Spesifikasinya adalah anak-anak dari elemen .<Specifications>
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;
Perhatikan hal berikut ini dari kueri sebelumnya:
Ekspresi
/p1:ProductDescription/p1:Specifications/*mengembalikan turunan elemen dari<Specifications> .Ekspresi
order by (local-name($a))mengurutkan urutan menurut bagian lokal dari nama elemen.
Berikut hasilnya:
<Color>Available in most colors</Color>
<Material>Aluminum Alloy</Material>
<ProductLine>Mountain bike</ProductLine>
<RiderExperience>Advanced to Professional riders</RiderExperience>
<Style>Unisex</Style>
Simpul di mana ekspresi pengurutan mengembalikan kosong diurutkan ke awal urutan, seperti yang ditunjukkan dalam contoh berikut:
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
');
Berikut hasilnya:
<Person />
<Person Name="A" />
<Person Name="B" />
Anda dapat menentukan beberapa kriteria pengurutan, seperti yang diperlihatkan dalam contoh berikut. Kueri dalam contoh ini mengurutkan <Employee> elemen terlebih dahulu menurut Judul lalu menurut nilai atribut Administrator.
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
');
Berikut hasilnya:
<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" />
Keterbatasan
Ini adalah batasannya:
Ekspresi pengurutan harus dititik secara homogen. Ini diperiksa secara statis.
Mengurutkan urutan kosong tidak dapat dikontrol.
Kata kunci
order bypaling kosong, kosong terbesar, dan kolase tidak didukung