使用SQL Server遍历XML“表兄弟”

Dji*_*eus 5 xml sql-server xpath

我将以下XML文档存储在TSQL变量中,其XML类型为:

<root>
  <parent>
    <child>Alice</child>
    <child>Bob</child>
    <child>Carol</child>
  </parent>
  <house>
    <room><id>1</id></room>
    <room><id>2</id></room>
    <room><id>3</id></room>
  </house>
</root>
Run Code Online (Sandbox Code Playgroud)

我想遍历“表兄弟”节点(即,其父母是兄弟姐妹的节点),并在表中每次迭代插入一行,每个表亲插入一行。因此结果将是这样的:

Child | Room
------------
Alice | 1
Bob   | 2
Carol | 3
Run Code Online (Sandbox Code Playgroud)

(事实上​​,我知道孩子的房间很多)。

我觉得这是一个简单的任务,但似乎找不到办法。我是SQL Server和XPath的初学者,可能缺少寻找文档的术语。

到目前为止,我尝试过的工作是进行迭代,说出child元素,然后尝试从中读取匹配的room元素,ROW_NUMBER以选择想要的房间:

INSERT INTO children (child, room)
SELECT 
  child = T.Item.value('(../parent/child/text())[' + (ROW_NUMBER() OVER(ORDER BY T.Item)) + ']', 'VARCHAR(10)'),
  room = T.Item.value('(id/text())[1]', 'CHAR(1)')
FROM   
  @XML.nodes('root/house/room') AS T(Item)
Run Code Online (Sandbox Code Playgroud)

但是SQL Server抱怨说,value()只接受字符串文字作为第一个参数(那是什么限制??)。

关于如何简单地做到这一点的任何想法?

TT.*_*TT. 5

不知道这是最好还是最短的方法,但是会产生您需要的输出:

DECLARE @x XML='
<root>
  <parent>
    <child>Alice</child>
    <child>Bob</child>
    <child>Carol</child>
  </parent>
  <house>
    <room><id>1</id></room>
    <room><id>2</id></room>
    <room><id>3</id></room>
  </house>
</root>';

;WITH childs AS (
    SELECT
        n.e.value('.','NVARCHAR(128)') AS child,
        id=ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
    FROM
        @x.nodes('/root/parent/child') AS n(e)
),
room_ids AS (
    SELECT
        n.e.value('.','NVARCHAR(128)') AS room_id,
        id=ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
    FROM
        @x.nodes('/root/house/room/id') AS n(e)
)
SELECT
    c.child,
    r.room_id
FROM
    childs AS c
    INNER JOIN room_ids AS r ON
        r.id=c.id
ORDER BY
    c.id;
Run Code Online (Sandbox Code Playgroud)