类型系统 (XQuery)

适用于:SQL Server

XQuery 对于架构类型是强类型语言,对于非类型化的数据是弱类型语言。 预定义的 XQuery 类型包括:

本主题还说明了下列内容:

XML 架构的内置类型

XML 架构的内置类型具有预定义的命名空间前缀 xs。 其中一些类型包括 xs:integerxs:string。 所有这些内置类型都支持。 您可以在创建 XML 架构集合时使用这些类型。

当查询类型化的 XML 时,节点的静态和动态类型由与正被查询的列或变量相关联的 XML 构架集合确定。 有关静态和动态类型的详细信息,请参阅 表达式上下文和查询计算 (XQuery) 。 例如,针对类型化的 xml 列 (Instructions) 指定以下查询。 表达式使用 instance of 验证返回的 LotSize 属性的类型化值是 xs:decimal 类型。

SELECT Instructions.query('  
   DECLARE namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
   data(/AWMI:root[1]/AWMI:Location[@LocationID=10][1]/@LotSize)[1] instance of xs:decimal  
') AS Result  
FROM Production.ProductModel  
WHERE ProductModelID=7  

此类型化信息是由与该列关联的 XML 架构集合提供的。

在 XPath 数据类型命名空间中定义的类型

命名空间中 http://www.w3.org/2004/07/xpath-datatypes 定义的类型具有预定义的前缀 xdt。 这些类型的限制条件如下:

  • 在创建 XML 架构集合时无法使用这些类型。 这些类型在 XQuery 类型系统中使用,并用于 XQuery 和静态类型化。 可以在 xdt 命名空间中强制转换为原子类型,例如 xdt:untypedAtomic

  • 查询非类型化的 XML 时,元素节点的静态和动态类型为 xdt:untyped,属性值的类型为 xdt:untypedAtomicquery () 方法的结果生成非类型化的 XML。 这意味着 XML 节点分别以 xdt:untypedxdt:untypedAtomic 的形式返回。

  • 不支持 xdt:dayTimeDurationxdt:yearMonthDuration 类型。

在以下示例中,针对非类型化的 XML 变量指定查询。 表达式 data(/a[1]) 返回一个原子值序列。 data() 函数返回元素 <a> 的类型化值。 由于被查询的 XML 是非类型化的,因此返回值的类型是 xdt:untypedAtomic。 因此,instance of 将返回 True。

DECLARE @x xml  
SET @x='<a>20</a>'  
SELECT @x.query( 'data(/a[1]) instance of xdt:untypedAtomic' )  

在下面的示例中,表达式 (/a[1]) 返回元素 <a> 的序列,而不是检索类型化值。 instance of 表达式使用元素测试来验证由此表达式返回的值是 xdt:untyped type 的元素节点。

DECLARE @x xml  
SET @x='<a>20</a>'  
-- Is this an element node whose name is "a" and type is xdt:untyped.  
SELECT @x.query( '/a[1] instance of element(a, xdt:untyped?)')  
-- Is this an element node of type xdt:untyped.  
SELECT @x.query( '/a[1] instance of element(*, xdt:untyped?)')  
-- Is this an element node?  
SELECT @x.query( '/a[1] instance of element()')  

注意

当查询类型化的 XML 实例并且查询表达式包含父轴时,所得到的节点的静态类型信息将不再可用。 但是,动态类型仍然与这些节点关联。

类型化值与字符串值

每个节点都带有类型化值和字符串值。 对于类型化的 XML 数据,类型化值的类型是与正被查询的列或变量相关联的 XML 架构集合提供的。 对于非类型化的 XML 数据,类型化值的类型为 xdt:untypedAtomic

可以使用 data () string () 函数检索节点的值:

在以下 XML 架构集合中 <root> ,定义了整数类型的 元素:

CREATE XML SCHEMA COLLECTION SC AS N'  
<schema xmlns="http://www.w3.org/2001/XMLSchema">  
      <element name="root" type="integer"/>  
</schema>'  
GO  

在下面的示例中,表达式首先检索 /root[1] 的类型化值,然后向其添加 3

DECLARE @x xml(SC)  
SET @x='<root>5</root>'  
SELECT @x.query('data(/root[1]) + 3')  

在下一个示例中,表达式将失败,因为表达式中的 string(/root[1]) 返回字符串类型值。 然后此值将传递给只接受数值类型值作为操作数的算术运算符。

-- Fails because the argument is string type (must be numeric primitive type).  
DECLARE @x xml(SC)  
SET @x='<root>5</root>'  
SELECT @x.query('string(/root[1]) + 3')  

下面的示例计算 LaborHours 属性的总计。 函数data()从产品模型的所有元素中<Location>检索属性的类型化值。LaborHours 根据与列关联的 Instruction XML 架构, LaborHoursxs:decimal 类型。

SELECT Instructions.query('   
DECLARE namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";   
             sum(data(//AWMI:Location/@LaborHours))   
') AS Result   
FROM Production.ProductModel   
WHERE ProductModelID=7  

此查询将返回结果 12.75。

注意

在此示例中显式使用 data () 函数仅用于说明。 如果未指定, sum () 将隐式应用 data () 函数来提取节点的类型化值。

另请参阅

SQL Server Profiler 模板和权限
XQuery 基础知识