Variable scope in for and let clauses
A variable that is bound in a for or let clause is in scope for the sub-expressions that appear after the variable binding.
This means that a for or let clause can reference variables that are bound in earlier clauses or in earlier bindings in the same clause.
The following examples demonstrate variable scope in for or let clauses. They assume that the PORDER column in the PURCHASEORDER table contains the following data:
<ipo:purchaseOrder
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ipo="http://www.example.com/IPO"
orderDate="2008-12-01">
<shipTo exportCode="1" xsi:type="ipo:UKAddress">
<name>Helen Zoe</name>
<street>55 Eden Street</street>
<city>San Jose</city>
<state>CA</state>
<postcode>CB1 1JR</postcode>
</shipTo>
<shipTo exportCode="1" xsi:type="ipo:UKAddress">
<name>Joe Lee</name>
<street>66 University Avenue</street>
<city>Palo Alto</city>
<state>CA</state>
<postcode>CB1 1JR</postcode>
</shipTo>
<billTo xsi:type="ipo:USAddress">
<name>Robert Smith</name>
<street>8 Oak Avenue</street>
<city>Old Town</city>
<state>PA</state>
<zip>95819</zip>
</billTo>
<items>
<item partNum="833-AA">
<productName>Lapis necklace</productName>
<quantity>1</quantity>
<USPrice>99.95</USPrice>
<ipo:comment>Want this for the holidays!</ipo:comment>
<shipDate>2008-12-05</shipDate>
</item>
<item partNum="945-ZG">
<productName>Sapphire Bracelet</productName>
<quantity>2</quantity>
<USPrice>178.99</USPrice>
<shipDate>2009-01-03</shipDate>
</item>
</items>
</ipo:purchaseOrder>
The
following example shows that a variable can be bound in a clause and
referenced in a later clause. In the SELECT statement, the FLWOR expression
has the following clauses:
- A let clause that binds the variable
$item
. - A for clause that references
$item
and binds the variable$pn
. - A let clause that references both
$item
and$pn
and binds the variables$n
and$q
.
SELECT XMLQUERY(
'declare namespace ipo="http://www.example.com/IPO";
let $item := $po/ipo:purchaseOrder/items/item
for $pn in $item/@partNum
let $n := $item[@partNum = $pn]/productName,
$q := $item[@partNum = $pn]/fn:sum(quantity)
return fn:concat("Quantity of ", $n, " = ", $q, ", ")'
PASSING PORDER as "po")
FROM PURCHASEORDER
The SELECT statement results in the
following output:Quantity of Lapis necklace = 1, Quantity of Sapphire Bracelet = 2,
The
following example shows that two variables with the same name can
be bound and referenced within the same scope. In the SELECT statement,
the FLWOR expression has the following clauses:
- A let clause that binds a variable named
$iteration
to 0. - A for clause that references a variable named
$po
that was bound by the PASSING clause, and binds a new$po
variable. - A let clause that references the
$iteration
variable from the first let clause, and binds another variable named$iteration
.
SELECT XMLQUERY(
'declare namespace ipo="http://www.example.com/IPO";
let $iteration := 0
return
for $po in $po/ipo:purchaseOrder/items/item/USPrice
return
let $iteration := $iteration + 1
return
<test iteration="{$iteration}">{$po}</test>'
PASSING PORDER as "po") FROM PURCHASEORDER
The
SELECT statement results in the following output:<test iteration="1">
<USPrice xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ipo="http://www.example.com/IPO">
99.95
</USPrice>
</test>
<test iteration="1">
<USPrice xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ipo="http://www.example.com/IPO">
178.99
</USPrice>
</test>