SQL Server XQuery 学习笔记(六)

来源:互联网 发布:淘宝美工尺寸 编辑:程序博客网 时间:2024/06/06 05:05

 

7、FLWOR 语句和迭代

FLWOR 依次表示 for、let、where、order by、return。

(1)   最简单的 FLWOR 语句类似于:

for 变量 in 输入序列 return 返回值

输入序列顾名思义是接受一个序列,序列可以直接编写也可以通过 XQuery表达式获取。如:

declare @x xml

set @x='<root><a>1</a><a>2</a><a>3</a></root>'

select @x.query('for $i in (1, 2, 3) return $i')

select @x.query('for $i in //a return $i')

select @x.query('for $i in //a return $i + 1')

注意上面最后两个语句的区别,前者返回一个节点序列,而后者返回原子值序列。其实后者相当于:

select @x.query('for $i in //a return data($i) + 1')

(2)   for … in … return 允许嵌套

select @x.query('for $i in

          for $a in (1,2,3) return $a + 1

return $i')

因为SQL Server 的输入序列不接收用户构造的 XML 序列,所以下面的方式将会引发错误:

select @x.query('for $i in

          for $a in (1,2,3) return <a>{$a}</a>

return $i')

(3)   where 子句

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 ))

where $a instance of xs:string

return $a')

该语句返回 test,如果 where 语句写为

where $a instance of xdt:untypedAtomic

将返回 111,即 /Root/a 节点包含的文本。

其实 where 相当于 Xpath 中的谓词测试,如:

declare @x xml

set @x='<ROOT><a><b>1</b></a><a /></ROOT>'

SELECT @x.query('for $a in //a where $a/* return $a')

这个语句返回 <a><b>1</b></a>,因为对于第二个 a 节点来说,$a/* 即 //a[2]/* 是一个空序列,此时 where 子句返回 false,因此该节点被过滤掉。

(4)   let 子句

SQL Server 2005 并不支持 let 子句,这是 SQL Server 2008 中新增的特性。样例:

declare @x xml

set @x='<ROOT><a><b>1</b></a><a /></ROOT>'

SELECT @x.query('

for $a in (3, 6, 9)

let $s := $a * $a

return <value>Square({$a}) = {$s}</value>

')

(5)   多个变量绑定

declare @x xml

set @x='<Manu ID="1" Name="SomeBike" >

<Location ID="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 ID="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>

</Manu>'

SELECT @x.query('

   for $Loc in /Manu/Location,

       $FirstStep in $Loc/Step[1]

   return

       <Loc Id="{$Loc/@ID}">{$FirstStep}</Loc>

')

第二个变量不是必须和第一个变量相关,如上面的 $FirstStep 也可以为 $FirstStep in //Step[1],当然,这样会导致不同的结果。

另外,多变量绑定似乎和 for … in 的嵌套是一回事,如

SELECT @x.query('

   for $Loc in /Manu/Location

       for $FirstStep in $Loc/Step[1]

   return

       <Loc Id="{$Loc/@ID}">{$FirstStep}</Loc>

')

返回的结果是一样的,但 MSDN 中未明确说明。

(6)   order by 子句

没什么好说的,就是排序,与 SQL 语句类似,降序的写法为

order by XXX descending

排序关键字必须是单一或空的序列,系统会隐式调用 data() 方法计算出原子值。

排序中可使用函数,如:

order by count($Loc/Step)

可按属性排序:order by $Loc/@ID

可按某个子节点值排序:order by $Loc/Step[1]

可按元素名称排序:order by local-name($Loc)

可指定多个排序关键字,同 SQL。

原创粉丝点击