类型系统 (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 () 函数检索节点的值:
data Function (XQuery) 返回节点的类型化值。
字符串 Function (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 () 函数来提取节点的类型化值。