XQueries Involving Order
Applies to: SQL Server
Relational databases do not have a concept of sequence. For example, you cannot make a request such as "Get the first customer from the database." However, you can query an XML document and retrieve the first <Customer> element. Then, you will always retrieve the same customer.
This topic illustrates queries based on the sequence in which nodes appear in the document.
Examples
A. Retrieve manufacturing steps at the second work center location for a product
For a specific product model, the following query retrieves manufacturing steps at the second work center location in a sequence of work center locations in the manufacturing process.
SELECT Instructions.query('
declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
<ManuStep ProdModelID = "{sql:column("Production.ProductModel.ProductModelID")}"
ProductModelName = "{ sql:column("Production.ProductModel.Name") }" >
<Location>
{ (//AWMI:root/AWMI:Location)[2]/@* }
<Steps>
{ for $s in (//AWMI:root/AWMI:Location)[2]//AWMI:step
return
<Step>
{ string($s) }
</Step>
}
</Steps>
</Location>
</ManuStep>
') as Result
FROM Production.ProductModel
WHERE ProductModelID=7
Note the following from the previous query:
The expressions in the curly braces are replaced by the result of its evaluation. For more information, see XML Construction (XQuery).
@* retrieves all the attributes of the second work center location.
The FLWOR iteration (FOR ... RETURN) retrieves all the <
step
> child elements of the second work center location.The sql:column() function (XQuery) includes the relational value in the XML that is being constructed.
This is the result:
<ManuStep ProdModelID="7" ProductModelName="HL Touring Frame">
<Location LocationID="20" SetupHours="0.15"
MachineHours="2" LaborHours="1.75" LotSize="1">
<Steps>
<Step>Assemble all frame components following blueprint 1299.</Step>
...
</Steps>
</Location>
</ManuStep>
The previous query retrieves just the text nodes. If you want the whole <step
> element returned instead, remove the string() function from the query:
B. Find all the material and tools used at the second work center location in the manufacturing of a product
For a specific product model, the following query retrieves the tools and materials used at the second work center location in the sequence of work center locations in the manufacturing process.
SELECT Instructions.query('
declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
<Location>
{ (//AWMI:root/AWMI:Location)[1]/@* }
<Tools>
{ for $s in (//AWMI:root/AWMI:Location)[1]//AWMI:step//AWMI:tool
return
<Tool>
{ string($s) }
</Tool>
}
</Tools>
<Materials>
{ for $s in (//AWMI:root/AWMI:Location)[1]//AWMI:step//AWMI:material
return
<Material>
{ string($s) }
</Material>
}
</Materials>
</Location>
') as Result
FROM Production.ProductModel
where ProductModelID=7
Note the following from the previous query:
The query constructs the <Loca
tion
> element and retrieves its attribute values from the database.It uses two FLWOR (for...return) iterations: one to retrieve tools and one to retrieve the material used.
This is the result:
<Location LocationID="10" SetupHours=".5"
MachineHours="3" LaborHours="2.5" LotSize="100">
<Tools>
<Tool>T-85A framing tool</Tool>
<Tool>Trim Jig TJ-26</Tool>
<Tool>router with a carbide tip 15</Tool>
<Tool>Forming Tool FT-15</Tool>
</Tools>
<Materials>
<Material>aluminum sheet MS-2341</Material>
</Materials>
</Location>
C. Retrieve the first two product feature descriptions from the product catalog
For a specific product model, the query retrieves the first two feature descriptions from the <Features
> element in the product model catalog.
SELECT CatalogDescription.query('
declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
<ProductModel ProductModelID= "{ data( (/p1:ProductDescription/@ProductModelID)[1] ) }"
ProductModelName = "{ data( (/p1:ProductDescription/@ProductModelName)[1] ) }" >
{
for $F in /p1:ProductDescription/p1:Features
return
$F/*[position() <= 2]
}
</ProductModel>
') as x
FROM Production.ProductModel
where ProductModelID=19
Note the following from the previous query:
The query body constructs XML that includes the <ProductModel
> element that has the ProductModelID and ProductModelName attributes.
- The query uses a FOR ... RETURN loop to retrieve the product model feature descriptions. The position() function is used to retrieve the first two features.
This is the result:
<ProductModel ProductModelID="19" ProductModelName="Mountain 100">
<p1:Warranty
xmlns:p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">
<p1:WarrantyPeriod>3 year</p1:WarrantyPeriod>
<p1:Description>parts and labor</p1:Description>
</p1:Warranty>
<p2:Maintenance
xmlns:p2="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">
<p2:NoOfYears>10</p2:NoOfYears>
<p2:Description>maintenance contact available through your dealer
or any AdventureWorks retail store.
</p2:Description>
</p2:Maintenance>
</ProductModel>
D. Find the first two tools used at the first work center location in the manufacturing process of the product
For a product model, this query returns the first two tools used at the first work center location in the sequence of work center locations in the manufacturing process. The query is specified against the manufacturing instructions stored in the Instructions column of the Production.ProductModel table.
SELECT Instructions.query('
declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
for $Inst in (//AWMI:root/AWMI:Location)[1]
return
<Location>
{ $Inst/@* }
<Tools>
{ for $s in ($Inst//AWMI:step//AWMI:tool)[position() <= 2]
return
<Tool>
{ string($s) }
</Tool>
}
</Tools>
</Location>
') as Result
FROM Production.ProductModel
where ProductModelID=7
This is the result:
<Location LocationID="10" SetupHours=".5"
MachineHours="3" LaborHours="2.5" LotSize="100">
<Tools>
<Tool>T-85A framing tool</Tool>
<Tool>Trim Jig TJ-26</Tool>
</Tools>
</Location>
E. Find the last two manufacturing steps at the first work center location in the manufacturing of a specific product
The query uses the last() function to retrieve the last two manufacturing steps.
SELECT Instructions.query('
declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
<LastTwoManuSteps>
<Last-1Step>
{ (/AWMI:root/AWMI:Location)[1]/AWMI:step[(last()-1)]/text() }
</Last-1Step>
<LastStep>
{ (/AWMI:root/AWMI:Location)[1]/AWMI:step[last()]/text() }
</LastStep>
</LastTwoManuSteps>') as Result
FROM Production.ProductModel
where ProductModelID=7
This is the result:
<LastTwoManuSteps>
<Last-1Step>When finished, inspect the forms for defects per
Inspection Specification .</Last-1Step>
<LastStep>Remove the frames from the tool and place them in the
Completed or Rejected bin as appropriate.</LastStep>
</LastTwoManuSteps>
See Also
XML Data (SQL Server)
XQuery Language Reference (SQL Server)
XML Construction (XQuery)