• Aucun résultat trouvé

Additional Concepts

Dans le document SQL Server (Page 44-48)

There are a few concepts that you need to understand in order to fully grasp how XQuery works. An introduction to XQuery can be found in Chapter 5. Those concepts are the following:

❑ Sequence

❑ Atomization

❑ Quantification

❑ Type promotion

The first of these concepts, sequence, is discussed in the next section.

Sequence

A sequence is simply the result of an XQuery expression that contains a list of XML nodes and fragments as well as XSD types. An item is an individual entry in the sequence and can be a node of one of the fol-lowing types:

❑ Element

❑ Attribute

❑ Text

❑ Comment

❑ Document

❑ Processing instruction

The following example demonstrates how to construct a query that will return a single element sequence:

SELECT Instructions.query(‘

<Test>This is a test </Test>’) AS Result

FROM Production.ProductModel WHERE ProductModelID = 10

The result of this query returns the following:

<Test>This is a test</Test>

Not very impressive, but it does demonstrate that you have the ability to retrieve specific information from within your XML document. For example, the following query returns the first step (previously shown in Figure 2-2) from your original query:

SELECT Instructions.query(‘declare namespace MSAW=”http://schemas.microsoft.com/_

Sqlserver/2004/07/adventure-works/ProductModelManuInstructions”;

FOR $Inst in /MSAW:root Return

(

<step1> {string(($Inst/MSAW:Location[LocationID=50]/MSAW:step[1][1]} </step1>

)

‘) AS Result

FROM Production.ProductModel WHERE ProductModelID = 10 You should see the following results:

<step1>Insert aluminum sheet MS-6061 into tool T-99 framing tool</step1>

This query is almost identical to your original query, but what you told it to do was retrieve a more spe-cific value (or sequence) from the XML document.

Atomization

Atomization is the process of retrieving the typed value of an item, and many times it is implied. In cer-tain scenarios, atomization allows you to return the value of an item without having to query for it again. The following example queries the MachineHoursattribute from the previous example and returns multiple values. The first value is the original queried value. The second value uses the data() function to extract the same value and increments it by 1 (adds 1 to it). The third value matches the sec-ond value, but is returned automatically using atomization instead of using the data()function again.

SELECT Instructions.query (‘declare namespace MSAW=”http://schemas.microsoft.com/_

Sqlserver/2004/07/adventure-works/ProductModelManuInstructions”;

FOR $AW in / MSAW:root/ MSAW:Location[2]

Return

This says, “Take a look at the second Location node and return the MachineHours attribute. Now add 1 to it and return that value.” Your results should look similar to the following:

<AW OriginalMachineHours=”1.75” NewMachineHours=”2.75” NewMachineHours1=”2.75/>

Quantification

There are two types of quantification, Existential and Universal, which specify semantics for Boolean operators when applied to two sequences.

A quantified expression in XQuery uses the following syntax:

{ some | every } <variable> in <Expression> satisfies <Expression>

Existential

The Existential quantifier says that for any two sequences, if an item in the first sequence has a match in the second sequence based on the comparison operator used, then the return value is true. In other words, if a value in the first sequence matches a value in the second sequence based on a specific com-parison operator, then the return value is true.

Look at the following example:

SELECT Instructions.query (‘declare namespace MSAW=”http://schemas.microsoft.com/_

sqlserver/2004/07/adventure-works/ProductModelManuInstructions”;

if (every $AW in // MSAW:Location Satisfies $AW/@MachineHours) then

<return>All Locations have Machine Hours</return>

else

<return>Not all Locations have Machine Hours</return>

‘)

FROM Production.ProductModel

When you run this, you get the following in return:

<return>Not all locations have Machine Hours</return>

If you still have your Production.xml file open, take a look at each <Location>element and notice that not every <Location>element has a MachineHoursattribute, so your results are correct.

Now make the following changes to the thenand elseclauses and run the query again:

SELECT Instructions.query (‘declare namespace MSAW=”http://schemas.microsoft.com/_

sqlserver/2004/07/adventure-works/ProductModelManuInstructions”;

if {every $AW in // MSAW:Location satisfies $AW/@LocationID) then

<return>All Locations have a LocationID</return>

else

<return>Not all Locations have a LocationID</return>

‘)

FROM Production.ProductModel WHERE ProductModelID = 10

What results did you get? What you should get back is a little bit different message than the first exam-ple, stating that all locations have a LocationID, as follows:

<return>All Locations have a LocationID</return>

The reason for this is because in this last example the existential quantifier returned a value of true, meaning that for each location, a LocationID was found. That was not the case in the first example.

Universal

The Universal quantifier says that for any two sequences, if all items in the first sequence have a match in the second sequence, then the return value is true.

The following example looks to see if any of the pictures in the Product table has an angle of front:

SELECT CatalogDescription.value (‘declare namespace MSAW=”http://schemas.microsoft.com/_

sqlserver/2004/07/adventure-works/ProductModelManuInstructions”;

if {some $AW in //MSAW: ProductDescription/MSAW:Picture satisfies $AW/@MSAW:Angle=”front”

Your results should look like the following:

PictureAngleFront TRUE

There are two changes in this code you need to be aware of. First is the schema declaration. Second, you are looking to see if any of pictures have an Angleof front, so your XQuery statement uses some instead of every. If you had used everyand not all of the Picture elements had an Angleof frontthen your return value would be False.

Dans le document SQL Server (Page 44-48)