【发布时间】:2014-08-02 15:40:10
【问题描述】:
是否可以在nodes() 的 XQuery 语句中引用当前上下文节点?
示例
假设我在一个表/表变量中排序了 XML 数据,其中每个文档的一个部分通过属性引用另一部分中的元素。 (在下面,人物和职位是通过 ID 关联的。)
DECLARE @Data TABLE (
ID INT NOT NULL PRIMARY KEY,
XmlData XML NOT NULL
)
INSERT INTO @Data
VALUES (1, '<Root>
<People>
<Person id="1">Frank</Person>
<Person id="2">Joe</Person>
</People>
<Positions>
<Position assignedToPerson="1">Engineer</Position>
<Position assignedToPerson="2">Manager</Position>
</Positions>
</Root>'),
(2, '<Root>
<People>
<Person id="5">Bob</Person>
<Person id="6">Sam</Person>
</People>
<Positions>
<Position assignedToPerson="6">Mechanic</Position>
<Position assignedToPerson="5">Accountant</Position>
</Positions>
</Root>')
可以像这样生成人-位置配对的结果集:
SELECT
PersonID = person.value('@id', 'NVARCHAR(50)'),
Name = person.value('.', 'NVARCHAR(50)'),
Position = position.value('.', 'NVARCHAR(50)')
FROM @Data
CROSS APPLY XmlData.nodes('/Root/People/Person') People(person)
CROSS APPLY person.nodes('/Root/Positions/Position') Positions(position)
WHERE person.value('@id', 'NVARCHAR(50)')= position.value('@assignedToPerson[1]','NVARCHAR(50)')
+---------+--------+------------+
|个人ID |姓名 |职位 |
+---------+--------+------------+
| 1 |弗兰克 |工程师 |
| 2 |乔 |经理 |
| 5 |鲍勃 |会计师 |
| 6 |山姆 |机械师 |
+----------+--------+------------+
问题
第二个CROSS APPLY 每次调用时都会将相关XML 文档中定义的每个 位置分解为自己的行。结果是文档中的 每个 人与文档中定义的 每个 位置配对。在WHERE 子句中将结果集过滤为相关的人-职位对。
目标
我想通过在第二个 XQuery 中引用 People(person) 的上下文节点来消除 将所有人与每个位置匹配——类似这样:
SELECT
PersonID = person.value('@id', 'NVARCHAR(50)'),
Name = person.value('.', 'NVARCHAR(50)'),
Position = position.value('.', 'NVARCHAR(50)')
FROM @Data
CROSS APPLY XmlData.nodes('/Root/People/Person') People(person)
CROSS APPLY person.nodes('/Root/Positions/Position[@assignedToPerson={{**reference to @ID of context node**}}]') Positions(position)
我可以在第二个 CROSS APPLY 的 XQuery 中引用第一个 nodes() 上下文节点吗?
(使用 JOIN-based approach 不起作用,因为上述数据来自表,而不是 XML 变量。)
【问题讨论】:
标签: xml tsql xquery-sql