类型系统 (XQuery)
XQuery 对于架构类型是强类型语言,对于非类型化的数据是弱类型语言。预定义的 XQuery 类型包括:
http://www.w3.org/2001/XMLSchema 命名空间中 XML 架构的内置类型。
http://www.w3.org/2004/07/xpath-datatypes 命名空间中定义的类型。
本主题还说明了下列内容:
节点的类型化值与字符串值。
匹配由表达式返回的序列类型。
XML 架构的内置类型
XML 架构的内置类型具有预定义的命名空间前缀 xs。例如,xs:integer 和 xs: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 架构集合提供的。有关详细信息,请参阅 AdventureWorks2008R2 数据库中的 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:untyped 和 xdt:untypedAtomic 返回。
不支持 xdt:dayTimeDuration 和 xdt: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() 函数来检索节点的值:
data 函数 (XQuery)返回节点的类型化值。
string 函数 (XQuery)返回节点的字符串值。
在下列 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() 函数来提取节点的类型化值。 |