2

我需要以下输出

<name>Thomas Mapother</name>
<name>Tom Cruise</name>

使用以下 XML 和 XQuery FLOWR 表达式。

INSERT INTO XMLO1 VALUES ('<Contact>
<Names>
    <Name Type = "Legal">
        <First>Thomas</First>
        <Middle>T</Middle>
        <Last>Mapother</Last>
    </Name>
    <Name Type = "Stage">
        <First>Tom</First>
        <Middle>C</Middle>
        <Last>Cruise</Last>
    </Name>
</Names>
</Contact>')

我尝试了以下查询。但它返回不同的输出。

SELECT xDoc.query('let $names := Contact/Names/Name
return <name>{
    for $x in $names
    return ($x/First,$x/Last)}
</name>')
FROM XMLO1
4

2 回答 2

2

从这个以及从Return multiple XML nodes and Custom parent tag using FLWOR XQuery来看,我认为您对 FLWOR 表达式的工作方式有点困惑。

在另一个问题中,您只需要一个包装元素 ( oldPlanes),但是您错误地在returnFLWOR 表达式的子句中创建了该元素,该子句为该子句选择的每个节点执行一次for。在这个问题中,您犯了相反的错误:您希望输入中name的每个元素都有一个元素Name,因此您需要在return子句中生成它。

所以而不是

return <name>{
    for $x in $names
    return ($x/First,$x/Last)}
</name>

你要

return 
    for $x in $names
    return <name>{($x/First,$x/Last)}</name>

再次,它可以简化为

return $names/<name>{(First,Last)}</name>

许多从 SQL 背景开始使用 XQuery 的人会错误地认为每个查询都必须是 FLWOR 表达式。事实上,绝大多数查询不需要变量,也不需要 FLWOR。

于 2019-06-28T12:01:12.063 回答
2

像这样的东西:

select xDoc.query('
for $x in Contact/Names/Name
return element Name {concat($x/First[1]," ", $x/Last[1])}
')
from XMLO1

或切碎并重新组合(会更快):

select T.X.value('(First/text())[1]', 'nvarchar(100)')+' '+
         T.X.value('(Last/text())[1]', 'nvarchar(100)')
from XMLO1
  cross apply xDoc.nodes('Contact/Names/Name') as T(X)
for xml path('Name');
于 2019-06-28T09:39:53.433 回答