类型系统 (XQuery)

适用范围:SQL Server

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

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

XML 架构的内置类型

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

当查询类型化的 XML 时,节点的静态和动态类型由与正被查询的列或变量相关联的 XML 构架集合确定。 有关静态和动态类型的详细信息,请参阅表达式上下文和查询评估(XQuery)。 例如,针对类型化的 xmlInstructions() 指定以下查询。 表达式使用 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:untypedAtomic。 query() 方法的结果生成非类型化的 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 架构, LaborHours xs :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 基础知识