SequenceType 表达式 (XQuery)
适用范围:SQL Server
在 XQuery 中,值始终是序列。 值类型称为序列类型。 序列类型可在 XQuery 表达式的实例中使用。 当需要引用 XQuery 表达式中的类型时,将使用 XQuery 规范中说明的 SequenceType 语法。
原子类型名称也可以在强制转换中 用作 XQuery 表达式。 在 SQL Server 中, 在 SequenceType 上作为 XQuery 表达式的实例 和 强制转换 部分受支持。
instance of 运算符
运算符 的 实例可用于确定指定表达式值的动态或运行时类型。 例如:
Expression instance of SequenceType[Occurrence indicator]
请注意, instance of
运算符 Occurrence indicator
指定生成的序列中的基数、项数。 如果未指定,则假定基数为 1。 在 SQL Server 中,仅支持问号 (?) 出现指示器。 出现指示器指示Expression
可以返回零项或一项。 如果指定了 ?匹配指示器,instance of
则无论Expression
返回单一实例还是空序列,当类型与指定的SequenceType
类型匹配时Expression
返回 True。
如果未指定 ?匹配指示器,sequence of
则仅当类型与指定的类型匹配Type
并Expression
返回单一实例时Expression
,才返回 True。
注意 SQL Server 不支持加号 (+) 和星号 (*) 出现指示器。
以下示例演示了 XQuery 运算符的实例的使用。
示例 A
以下示例创建一个 xml 类型变量,并针对它指定查询。 查询表达式将指定 instance of
运算符以确定第一个操作数返回的值的动态类型是否与第二个操作数中指定的类型相匹配。
以下查询返回 True,因为 125 值是指定类型 xs:integer 的实例:
declare @x xml
set @x=''
select @x.query('125 instance of xs:integer')
go
以下查询将返回 True,因为由第一个操作数中的 /a[1] 表达式返回的值是一个元素:
declare @x xml
set @x='<a>1</a>'
select @x.query('/a[1] instance of element()')
go
同样,在以下查询中,instance of
将返回 True,因为在第一个表达式中表达式的值类型是属性:
declare @x xml
set @x='<a attr1="x">1</a>'
select @x.query('/a[1]/@attr1 instance of attribute()')
go
在下列示例中,表达式 data(/a[1]
将返回类型为 xdt:untypedAtomic 的原子值。 因此,instance of
返回 True。
declare @x xml
set @x='<a>1</a>'
select @x.query('data(/a[1]) instance of xdt:untypedAtomic')
go
在以下查询中,表达式 data(/a[1]/@attrA
将返回非类型化的原子值。 因此,instance of
返回 True。
declare @x xml
set @x='<a attrA="X">1</a>'
select @x.query('data(/a[1]/@attrA) instance of xdt:untypedAtomic')
go
示例 B
在此示例中,将查询 AdventureWorks 示例数据库中的类型化的 XML 列。 类型化信息由与被查询的列关联的 XML 架构集合提供。
在表达式中, data() 根据与列关联的架构返回 ProductModelID 属性的类型化值 xs:string。 因此,instance of
返回 True。
SELECT CatalogDescription.query('
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
data(/PD:ProductDescription[1]/@ProductModelID) instance of xs:string
') as Result
FROM Production.ProductModel
WHERE ProductModelID = 19
有关详细信息,请参阅 类型化的 XML 与非类型化的 XML 的比较。
以下查询使用布尔 instance of
表达式来确定 LocationID 属性是否为 xs:integer 类型:
SELECT Instructions.query('
declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
/AWMI:root[1]/AWMI:Location[1]/@LocationID instance of attribute(LocationID,xs:integer)
') as Result
FROM Production.ProductModel
WHERE ProductModelID=7
对 CatalogDescription 非类型化的 XML 列指定以下查询。 类型化信息由与此列关联的 XML 架构集合提供。
查询使用 element(ElementName, ElementType?)
表达式中的 instance of
测试来验证 /PD:ProductDescription[1]
是否返回特定名称和类型的元素节点。
SELECT CatalogDescription.query('
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
/PD:ProductDescription[1] instance of element(PD:ProductDescription, PD:ProductDescription?)
') as Result
FROM Production.ProductModel
where ProductModelID=19
该查询返回 True。
示例 C
使用联合类型时, instance of
SQL Server 中的表达式有一个限制:具体而言,当元素或属性的类型为联合类型时, instance of
可能无法确定确切的类型。 因此,查询将返回 False,除非用于 SequenceType 中的原子类型在简单类型层次结构中是表达式的实际类型的最高父级。 即以 SequenceType 指定的原子类型必须是任意简单类型的直接子级。 有关类型层次结构的信息,请参阅 XQuery 中的类型强制转换规则。
下一个查询示例将执行以下操作:
使用联合类型创建 XML 架构集合,在其中定义诸如整数或字符串等类型。
使用 XML 架构集合声明类型化的 xml 变量。
将示例 XML 实例分配给变量。
查询变量以说明
instance of
在处理联合类型时的行为。
以下是查询语句:
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
以下查询将返回 False,因为在 instance of
表达式中指定的 SequenceType 不是指定表达式的实际类型的最高父级。 也就是说, <TestElement
> 该值为整数类型。 最高父级为 xs:decimal。 但是,未将它指定为 instance of
运算符的第二个操作数。
SET QUOTED_IDENTIFIER ON
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:integer')
go
因为 xs:integer 的最高父级是 xs:decimal,所以,如果您要修改查询并在查询中将 xs:decimal 指定为 SequenceType,则查询将返回 True。
SET QUOTED_IDENTIFIER ON
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')
go
示例 D
在此示例中,首先创建一个 XML 架构集合,并将其用于键入 xml 变量。 然后,查询类型化的 xml 变量以说明 instance of
功能。
以下 XML 架构集合定义 myType 类型的简单类型、myType 和元素 <root
>:
drop xml schema collection SC
go
CREATE XML SCHEMA COLLECTION SC AS '
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="myNS" xmlns:ns="myNS"
xmlns:s="https://schemas.microsoft.com/sqlserver/2004/sqltypes">
<import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes"/>
<simpleType name="myType">
<restriction base="s:varchar">
<maxLength value="20"/>
</restriction>
</simpleType>
<element name="root" type="ns:myType"/>
</schema>'
Go
现在创建类型化的 xml 变量并对其进行查询:
DECLARE @var XML(SC)
SET @var = '<root xmlns="myNS">My data</root>'
SELECT @var.query('declare namespace sqltypes = "https://schemas.microsoft.com/sqlserver/2004/sqltypes";
declare namespace ns="myNS";
data(/ns:root[1]) instance of ns:myType')
go
由于 myType 类型仅限于从 varchar 类型(在 sqltypes 架构中定义)派生,因而 instance of
也将返回 True。
DECLARE @var XML(SC)
SET @var = '<root xmlns="myNS">My data</root>'
SELECT @var.query('declare namespace sqltypes = "https://schemas.microsoft.com/sqlserver/2004/sqltypes";
declare namespace ns="myNS";
data(/ns:root[1]) instance of sqltypes:varchar?')
go
示例 E
在下列示例中,表达式将检索 IDREFS 属性的值之一,并使用 instance of
来确定该值是否是 IDREF 类型。 该示例执行以下操作:
创建一个 XML 架构集合,其中<>
Customer
元素具有 OrderList IDREFS 类型属性,并且<Order
>该元素具有 OrderID ID 类型属性。创建类型化的 xml 变量并向其分配示例 XML 实例。
对变量指定查询。 查询表达式从第一个订单列表的IDERS 类型属性中检索第一 <
Customer
>个订单 ID 值。 检索的值是 IDREF 类型。 因此,instance of
返回 True。
create xml schema collection SC as
'<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:Customers="Customers" targetNamespace="Customers">
<element name="Customers" type="Customers:CustomersType"/>
<complexType name="CustomersType">
<sequence>
<element name="Customer" type="Customers:CustomerType" minOccurs="0" maxOccurs="unbounded" />
</sequence>
</complexType>
<complexType name="OrderType">
<sequence minOccurs="0" maxOccurs="unbounded">
<choice>
<element name="OrderValue" type="integer" minOccurs="0" maxOccurs="unbounded"/>
</choice>
</sequence>
<attribute name="OrderID" type="ID" />
</complexType>
<complexType name="CustomerType">
<sequence minOccurs="0" maxOccurs="unbounded">
<choice>
<element name="spouse" type="string" minOccurs="0" maxOccurs="unbounded"/>
<element name="Order" type="Customers:OrderType" minOccurs="0" maxOccurs="unbounded"/>
</choice>
</sequence>
<attribute name="CustomerID" type="string" />
<attribute name="OrderList" type="IDREFS" />
</complexType>
</schema>'
go
declare @x xml(SC)
set @x='<CustOrders:Customers xmlns:CustOrders="Customers">
<Customer CustomerID="C1" OrderList="OrderA OrderB" >
<spouse>Jenny</spouse>
<Order OrderID="OrderA"><OrderValue>11</OrderValue></Order>
<Order OrderID="OrderB"><OrderValue>22</OrderValue></Order>
</Customer>
<Customer CustomerID="C2" OrderList="OrderC OrderD" >
<spouse>John</spouse>
<Order OrderID="OrderC"><OrderValue>33</OrderValue></Order>
<Order OrderID="OrderD"><OrderValue>44</OrderValue></Order>
</Customer>
<Customer CustomerID="C3" OrderList="OrderE OrderF" >
<spouse>Jane</spouse>
<Order OrderID="OrderE"><OrderValue>55</OrderValue></Order>
<Order OrderID="OrderF"><OrderValue>55</OrderValue></Order>
</Customer>
<Customer CustomerID="C4" OrderList="OrderG" >
<spouse>Tim</spouse>
<Order OrderID="OrderG"><OrderValue>66</OrderValue></Order>
</Customer>
<Customer CustomerID="C5" >
</Customer>
<Customer CustomerID="C6" >
</Customer>
<Customer CustomerID="C7" >
</Customer>
</CustOrders:Customers>'
select @x.query(' declare namespace CustOrders="Customers";
data(CustOrders:Customers/Customer[1]/@OrderList)[1] instance of xs:IDREF ? ') as XML_result
实现限制
限制如下:
与运算符进行比较
instance of
时,不支持 schema-element() 和 schema-attribute() 序列类型。不支持完整序列(如
(1,2) instance of xs:integer*
)。使用指定类型名称的 元素() 序列类型形式时,
element(ElementName, TypeName)
类型必须用问号(?)限定。 例如,element(Title, xs:string?)
指示元素可能为空。 SQL Server 不支持使用instance of
xsi:nil 属性的运行时检测。如果值
Expression
来自类型化为联合的元素或属性,则 SQL Server 只能标识从中派生值的基元(而不是派生)类型。 例如,如果 <e1
> 定义为具有静态类型 (xs:integer | xs:string),则以下内容将返回 False。data(<e1>123</e1>) instance of xs:integer
而
data(<e1>123</e1>) instance of xs:decimal
将返回 True。对于 processing-instruction() 和 document-node() 序列类型,仅允许不使用参数的窗体。 例如,允许
processing-instruction()
,但不允许processing-instruction('abc')
。
cast as 运算符
转换为表达式可用于将值转换为特定数据类型。 例如:
Expression cast as AtomicType?
在 SQL Server 中,在问号 (?) 之后 AtomicType
是必需的。 例如,如以下查询所示, "2" cast as xs:integer?
将字符串值转换为整数:
declare @x xml
set @x=''
select @x.query('"2" cast as xs:integer?')
在以下查询中, data() 返回 ProductModelID 属性的类型化值(字符串类型)。 运算符 cast as
将值转换为 xs:integer。
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS PD)
SELECT CatalogDescription.query('
data(/PD:ProductDescription[1]/@ProductModelID) cast as xs:integer?
') as Result
FROM Production.ProductModel
WHERE ProductModelID = 19
此查询中不需要显式使用数据()。 cast as
表达式在输入表达式中执行隐式原子化。
构造函数
您可以使用原子类型来构造函数。 例如,可以使用 xs:integer() 构造函数,而不是使用cast as
运算符"2" cast as xs:integer?
,如以下示例所示:
declare @x xml
set @x=''
select @x.query('xs:integer("2")')
以下示例返回的 xs:date 值等于 2000-01-01Z。
declare @x xml
set @x=''
select @x.query('xs:date("2000-01-01Z")')
您还可以使用用户定义的原子类型的构造函数。 例如,如果与 XML 数据类型关联的 XML 架构集合定义了一个简单的类型, 则可以使用 myType() 构造函数返回该类型的值。
实现限制
不支持 XQuery 表达式 typeswitch、 castable 和 treat 。
强制 转换为原子类型后需要问号(?)。
不支持 xs:QName 作为强制转换的类型。 请改用 expanded-QName 。
xs:date、 xs:time 和 xs:datetime 需要时区,该时区由 Z 指示。
以下查询失败,因为未指定时区。
DECLARE @var XML SET @var = '' SELECT @var.query(' <a>{xs:date("2002-05-25")}</a>') go
通过向值添加时区指示符 Z,查询便可正常工作。
DECLARE @var XML SET @var = '' SELECT @var.query(' <a>{xs:date("2002-05-25Z")}</a>') go
结果如下:
<a>2002-05-25Z</a>