SQL Server XQuery 学习笔记(七)

 

8、条件表达式(if(…) then … else …)

注意一点:else 表达式是必须的,即使不需要该表达式,也必须返回一个空序列(),如

declare @v varchar(10), @x xml

set @v = 'First'

set @x = ''

select @x.query('if (sql:variable("@v") = "First") then "Yes" else ()')

一个相对复杂的查询的示例:

declare @x xml

set @x = '<root>

                <a type="node" childType="int"><b>1</b><b>2</b><b>3</b></a>

                <a type="node" childType="text"><b>s1</b><b>s2</b><b>s3</b></a>

                <a type="node" childType="double"><b>1.2</b><b>1.3</b></a>

</root>'

select @x.query('for $t in /root/a return

<result>

                { $t/@type } (: 选择属性,最终也是生成属性 :)

                { $t/@childType }

                {

                        for $i in $t/*[position() <=2]

                        return $i

                }

                {

                        if (count($t/*) > 2) then

                                <more /> (: 直接在大括号中构建子元素 :)

                        else()              

                }

</result>')

9、限定表达式

( some | every ) <var> in <Exp1> satisfies <Exp2>

some:存在量词,Exp1 选定的序列有任意一项满足 Exp2,返回 true。

every:全称量词,Exp2 选定的序列必须全部满足 Exp2,才返回 true。

Exp2 返回的结果可以是节点序列、空序列或布尔值。

样例:

declare @x xml

set @x = '<root>

                <a type="node" childType="int"><b>1</b><b>2</b><b>3</b></a>

                <a type="node" childType="text"><b>s1</b><b>s2</b><b>s3</b></a>

                <a type="node" childType="double"><b>1.2</b><b>1.3</b></a>

</root>'

select @x.query('if (every $i in //a satisfies count($i/*) = 3) then

        "Yes" else "No"')

select @x.query('every $i in //a satisfies $i/b') – 判断 a 是否均有节点 b

select @x.value('some $i in //a satisfies count($i/*) = 3', 'varchar(10)')

10、SequenceType 表达式

在 XQuery 中,值始终是序列。值类型称为系列类型,序列类型可以用在 instance of XQuery 表达式中。当需要引用 XQuery 中的表达式类型时,应使用 XQuery 规范中的 SequenceType 语法。

(1)   instance of 运算符

语法:Exp instance of SequenceTyep[基数]

若未指定基数,则默认为 1。基数可以为 ?、+、*,但 SQL Server 仅支持 “?”。”?” 表示 Exp 返回零项或一项,考虑下下面的例子:

Select @x.query('() instance of xs:integer?') – 有 ?,返回 true

Select @x.query('() instance of xs:integer') – 没有 ?,返回 false

l  对于非类型化节点的测试:

declare @x xml

set @x='<a attr1="x">1</a>'

select @x.query('/a[1] instance of element(a, xdt:untyped?)') -- true

select @x.query('data(/a[1]) instance of xdt:untypedAtomic') – true

l  通过 schema 自定义的类型,也可以使用 instance of 运算符:

create xml schema collection SC as '

<schema xmlns=http://www.w3.org/2001/XMLSchema

targetNamespace="SC" xmlns:sc="SC">

<element name="root" type="sc:custom" />

                        <complexType name="custom">

                                <sequence minOccurs="1" maxOccurs="unbounded">

                                        <element name="a" type="integer" />

                                </sequence>          

                        </complexType>

</schema>'

Go

declare @x xml(SC)

set @x = '<sc:root xmlns:sc="SC"><a>10</a><a>20</a></sc:root>'

select @x.query('declare namespace sc = "SC";

/sc:root[1] instance of element(sc:root, sc:custom?)')

注意命名空间的使用,set @x = '<sc:root xmlns:sc="SC"><a>10</a> <a>20</a></sc:root>' 这一句,也可以写成:

set @x = '<root xmlns="SC">

<a xmlns="">10</a><a xmlns="">20</a>

</root>'

如果写成

set @x = '<root xmlns="SC"><a>10</a><a>20</a></root>'

则会出现错误提示“预期的元素是 a,但指定的元素是 SC:a”。

l  如果在 schema 中定义了联合类型,对于使用联合类型的节点,SQL Server 在 XQuery 中可能无法判定该节点原子值所具有的真实类型。此时,可以判断联合类型中所包含的原子类型的顶级父类型。如:

CREATE XML SCHEMA COLLECTION MyTestSchema AS '

<schema xmlns="http://www.w3.org/2001/XMLSchema"

                  targetNamespace="http://ns" xmlns:ns="http://ns">

                  <simpleType name="MyUnionType">

                          <union memberTypes="integer string"/>

                  </simpleType>

                  <element name="TestElement" type="ns:MyUnionType"/>

</schema>'

Go

DECLARE @var XML(MyTestSchema)

SET @var = '<TestElement xmlns="http://ns">123</TestElement>'

SELECT @var.query('declare namespace ns="http://ns";

   data(/ns:TestElement[1]) instance of xs:decimal') – 返回 true

如果 data(/ns:TestElement[1]) instance of xs:decimal 换成

data(/ns:TestElement[1]) instance of xs:integer

则返回 false。因为 SQL Server 无法正确判定联合类型节点中节点原子值的真实原子类型,此时,应使用 xs:integer 的顶级父类型 xs:decimal 判定。

当然,仍然可以判定节点类型:

SELECT @var.query('declare namespace ns="http://ns";

       /ns:TestElement[1] instance of element(ns:TestElement, ns:MyUnionType?)')

(2)   cast as 运算符

语法:Exp cast as 原子类型?

在 SQL Server 中,“?”是必须的。另外,与日期时间相关的转换(xs:date、xs:time、xs:datetime)必须指定时区,时区由 Z 指定。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值