SequenceType 表达式 (XQuery)

适用于:SQL Server

在 XQuery 中,值始终是序列。 值类型称为序列类型。 序列类型可以在 XQuery 表达式 的实例 中使用。 当需要引用 XQuery 表达式中的类型时,将使用 XQuery 规范中说明的 SequenceType 语法。

原子类型名称也可以在 强制转换中用作 XQuery 表达式。 在 SQL Server中,部分支持在 SequenceTypes 上将 和 强制转换为 XQuery 表达式的实例

instance of 运算符

运算符 的实例 可用于确定指定表达式的值的动态或运行时类型。 例如:

  
Expression instance of SequenceType[Occurrence indicator]  

请注意, instance of 运算符 Occurrence indicator指定生成序列中的基数和项数。 如果未指定,则假定基数为 1。 在 SQL Server 中,仅支持问号 (?) 出现指示器。 事件指示器指示Expression可以返回零项或一项。 如果指定了 匹配项指示器,instance of则当类型与指定的 SequenceType匹配时Expression,无论Expression返回的是单一实例还是空序列,都会返回 True。

如果未指定 匹配项指示器, sequence of 则仅当 Expression 类型与指定的 匹配 TypeExpression 返回单一实例时,才返回 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 的比较

以下查询使用Boolean 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 ofSQL 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 实例。

  • 对变量指定查询。 查询表达式从第一个 的 OrderListIDERS 类型属性中检索第一个 <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  

实现限制

限制如下:

  • 不支持 将 schema-element () schema-attribute () 序列类型与 instance of 运算符进行比较。

  • 不支持完整序列(如 (1,2) instance of xs:integer*)。

  • 使用指定类型名称的 元素 () 序列类型的形式时, element(ElementName, TypeName)必须使用问号 (?) 限定类型。 例如,element(Title, xs:string?) 指示元素可能为空。 SQL Server不支持使用 instance ofxsi: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  

在此查询中不需要显式使用 data () 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 表达式 typeswitchcastabletreat

  • 强制转换为 需要原子类型后 (?) 问号。

  • 不支持将 xs:QName 作为强制转换的类型。 请改用 expanded-QName

  • xs:datexs:timexs: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>  
    

另请参阅

XQuery 表达式
类型系统 (XQuery)