类型系统 (XQuery)
适用范围:SQL Server
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 架构集合提供的。
在 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() 函数检索节点的值:
数据函数 (XQuery) 返回节点的类型化值。
字符串函数 (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() 函数来提取节点的类型化值。