原子化是提取项的类型化值的进程。在某些环境下,此进程是隐式进行的。某些 XQuery 运算符(如算术运算符和比较运算符)依赖于此进程。例如,将算术运算符直接应用于节点时,通过隐式调用数据函数,首先检索节点的类型化值。这将把原子值作为操作数传递给算术运算符。
例如,下面的查询将返回 LaborHours 属性的总数。在本例中,data() 被隐式应用于属性节点。
declare @x xml
set @x='<ROOT><Location LID="1" SetupTime="1.1" LaborHours="3.3" />
<Location LID="2" SetupTime="1.0" LaborHours="5" />
<Location LID="3" SetupTime="2.1" LaborHours="4" />
</ROOT>'
-- data() implicitly applied to the attribute node sequence.
SELECT @x.query('sum(/ROOT/Location/@LaborHours)')
虽然没有要求显式指定 data() 函数,但您也可以执行此操作:
SELECT @x.query('sum(data(ROOT/Location/@LaborHours))')
隐式原子化的另一个示例是使用算术运算符。+ 运算符需要原子值,将隐式应用 data() 来检索 LaborHours 属性的原子值。对 ProductModel 表中的类型为 xml 的 Instructions 列指定查询。下面的查询将返回 LaborHours 属性三次。在该查询中,请注意下列情况:
- 构造 OrignialLaborHours 属性时,原子化隐式应用于
$WC/@LaborHours
返回的单独序列。LaborHours 属性的类型化值被分配给 OrignialLaborHours。 - 在构造 UpdatedLaborHoursV1 属性时,算术运算符需要原子值。因此,data() 隐式应用于
$WC/@LaborHours
返回的 LaborHours 属性。然后,原子值 1 添加到该属性。属性 UpdatedLaborHoursV2 的构造显示了 data() 的显式应用(虽未要求)。
SELECT Instructions.query('
declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
for $WC in /AWMI:root/AWMI:Location[1]
return
<WC OriginalLaborHours = "{ $WC/@LaborHours }"
UpdatedLaborHoursV1 = "{ $WC/@LaborHours + 1 }"
UpdatedLaborHoursV2 = "{ data($WC/@LaborHours) + 1 }" >
</WC>') as Result
FROM Production.ProductModel
where ProductModelID=7
结果如下:
<WC OriginalLaborHours="2.5"
UpdatedLaborHoursV1="3.5"
UpdatedLaborHoursV2="3.5" />
原子化将导致简单类型、空集、静态类型的实例错误。
原子化还会发生在传递到函数的比较表达式参数、函数返回的值、cast() 表达式和子句按顺序传递的排序表达式中。