Xml 如何在XQuery中使用条件?
我有带地址的示例xml数据。它工作得很好,但有一个问题。我使用“/”来连接门牌号和公寓号,但如果没有公寓号,我会收到类似的信息:1/ 下面是我的例子:Xml 如何在XQuery中使用条件?,xml,tsql,xpath,sql-server-2012,xquery,Xml,Tsql,Xpath,Sql Server 2012,Xquery,我有带地址的示例xml数据。它工作得很好,但有一个问题。我使用“/”来连接门牌号和公寓号,但如果没有公寓号,我会收到类似的信息:1/ 下面是我的例子: declare @xml as xml = '<root> <Row> <proceeding> <signatures>V GU
declare @xml as xml = '<root>
<Row>
<proceeding>
<signatures>V GU 86/18</signatures>
<signatures>V GUp 9/19</signatures>
<signatures>V GUp 8/19</signatures>
</proceeding>
<entity>
<info>
<cleaned_name>Kate Smith</cleaned_name>
</info>
<address>
<town>London </town>
<house_number>1 </house_number>
<flat_number>1</flat_number>
<street>Downing Street</street>
<zip_code>00-001</zip_code>
</address>
<address>
<town>Yorkshire </town>
<house_number>1 </house_number>
<flat_number>1</flat_number>
<street>Morning Street</street>
<zip_code>00-999</zip_code>
</address>
</entity>
<entity>
<info>
<cleaned_name>John Smith</cleaned_name>
</info>
<address>
<town>Washington </town>
<house_number>1</house_number>
<flat_number>1</flat_number>
<street>Pennsylvania Avenue</street>
<zip_code>00-001</zip_code>
</address>
<address>
<town>Washington </town>
<house_number>1</house_number>
<flat_number></flat_number>
<street>Pennsylvania Avenue</street>
<zip_code>00-001</zip_code>
</address>
</entity>
</Row>
</root>'
select
isnull(STUFF(a.x.query('for $s in entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu'
,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
,isnull(STUFF(a.x.query('for $s in entity/address
return
<x>{concat(", ",($s/zip_code/text())[1]," "
,($s/town/text())[1]," "
,($s/street/text())[1]," "
,($s/house_number/text())[1],"/"
,($s/flat_number/text())[1]
)}</x>')
.query('for $a in distinct-values(/x/text()) return $a').value('.','varchar(max)'),1,2,''),'')
from @xml.nodes('/root/Row') as a(x);
将@xml声明为xml=
V GU 86/18
V GUp 9/19
V GUp 8/19
凯特·史密斯
这就是我想要的结果:
以下是我迄今为止所尝试的:
declare @v varchar(20)='house_number'
select
isnull(STUFF(a.x.query('for $s in entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu'
,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
,isnull(STUFF(a.x.query('if (sql:variable("@v")="") then for $s in entity/address
return
<x>{concat(", ",($s/zip_code/text())[1]," "
,($s/town/text())[1]," "
,($s/street/text())[1]," "
,($s/house_number/text())[1]
)}</x>
else
<x>{concat(", ",($s/zip_code/text())[1]," "
,($s/town/text())[1]," "
,($s/street/text())[1]," "
,($s/house_number/text())[1],"/"
,($s/flat_number/text())[1]
)}</x>
')
.query('for $a in distinct-values(/x/text()) return $a').value('.','varchar(max)'),1,2,''),'')
from @xml.nodes('/root/Row') as a(x);
declare@v varchar(20)='house_number'
挑选
isnull(STUFF(a.x.query('for$s in entity/info/name返回{concat(“,”,$s)}'))。值('.','varchar(max'),1,1','),'')为'Nazwa podmiotu'
,isnull(STUFF(a.x.query('for$s in proceduring/signatures返回{concat(,“,$s)}'))。值('.','varchar(max')),1,1',),'')为'Sygnatura'
,isnull(STUFF(a.x.query('if(sql:variable(“@v”)=”)然后用于实体/地址中的$s
返回
{concat(“,”,($s/zip_code/text())[1],“
,($s/town/text())[1],“”
,($s/street/text())[1],“”
,($s/house_number/text())[1]
)}
其他的
{concat(“,”,($s/zip_code/text())[1],“
,($s/town/text())[1],“”
,($s/street/text())[1],“”
,($s/house_number/text())[1],“/”
,($s/flat_number/text())[1]
)}
')
.query('for$a in distinct value(/x/text())返回$a')。value('.','varchar(max'),1,2','),'')
从@xml.nodes('/root/Row')开始,作为(x);
我收到以下错误:XQuery[query()]:在引用变量“$s”的作用域中找不到该变量。我想知道我是否能用那种方式实现我的目标 我用另一种方式做了,效果很好
select
isnull(STUFF(a.x.query('for $s in entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu'
,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
,isnull(STUFF(a.x.query('for $s in entity/address
return
if ($s/flat_number="")
then
<x>{concat(", ",($s/zip_code/text())[1]," "
,($s/town/text())[1]," "
,($s/street/text())[1]," "
,($s/house_number/text())[1]
)}</x>
else
<x>{concat(", ",($s/zip_code/text())[1]," "
,($s/town/text())[1]," "
,($s/street/text())[1]," "
,($s/house_number/text())[1],"/"
,($s/flat_number/text())[1]
)}</x>
')
.query('for $a in distinct-values(/x/text()) return $a').value('.','varchar(max)'),1,2,''),'')
from @xml.nodes('/root/Row') as a(x);
选择
isnull(STUFF(a.x.query('for$s in entity/info/name返回{concat(“,”,$s)}'))。值('.','varchar(max'),1,1','),'')为'Nazwa podmiotu'
,isnull(STUFF(a.x.query('for$s in proceduring/signatures返回{concat(,“,$s)}'))。值('.','varchar(max')),1,1',),'')为'Sygnatura'
,isnull(STUFF(a.x.query('用于实体/地址中的$s
返回
如果($s/flat_number=”“)
然后
{concat(“,”,($s/zip_code/text())[1],“
,($s/town/text())[1],“”
,($s/street/text())[1],“”
,($s/house_number/text())[1]
)}
其他的
{concat(“,”,($s/zip_code/text())[1],“
,($s/town/text())[1],“”
,($s/street/text())[1],“”
,($s/house_number/text())[1],“/”
,($s/flat_number/text())[1]
)}
')
.query('for$a in distinct value(/x/text())返回$a')。value('.','varchar(max'),1,2','),'')
从@xml.nodes('/root/Row')开始,作为(x);
好吧,在这种情况下,您的(我同时更改了)“如何使用LET”可能会有一个复兴:-)
试试这个:
select
isnull(STUFF(a.x.query('for $s in entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu'
,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
,isnull(STUFF(a.x.query('for $s in entity/address
let $houseFlat:=if($s/flat_number/text())
then concat(($s/house_number/text())[1],"/",($s/flat_number/text())[1])
else string(($s/house_number/text())[1])
return
<x>{concat(", ",($s/zip_code/text())[1]," "
,($s/town/text())[1]," "
,($s/street/text())[1]," "
,$houseFlat
)}</x>')
.query('for $a in distinct-values(/x/text()) return $a').value('.','varchar(max)'),1,2,''),'')
from @xml.nodes('/root/Row') as a(x);
选择
isnull(STUFF(a.x.query('for$s in entity/info/name返回{concat(“,”,$s)}'))。值('.','varchar(max'),1,1','),'')为'Nazwa podmiotu'
,isnull(STUFF(a.x.query('for$s in proceduring/signatures返回{concat(,“,$s)}'))。值('.','varchar(max')),1,1',),'')为'Sygnatura'
,isnull(STUFF(a.x.query('用于实体/地址中的$s
let$houseFlat:=if($s/flat\u number/text())
然后是concat($s/house_number/text())[1]、“/”、($s/flat_number/text())[1])
else字符串($s/house_number/text())[1])
返回
{concat(“,”,($s/zip_code/text())[1],“
,($s/town/text())[1],“”
,($s/street/text())[1],“”
,$houseFlat
)}')
.query('for$a in distinct value(/x/text())返回$a')。value('.','varchar(max'),1,2','),'')
从@xml.nodes('/root/Row')开始,作为(x);
但是-至少在这种情况下-distinct-values()
不会有帮助。由于房屋和街道编号中的1
和1/1
,两个地址不相同…我不太确定其他答案解决了什么问题,但对于标题中描述的问题,您可以替换
($s/house_number/text())[1],"/",($s/flat_number/text())[1]
在concat params中使用
string-join((($s/house_number/text())[1], ($s/flat_number/text())[1]), '/')
只有同时存在门牌号和公寓号时,才会插入“/”
我不明白为什么需要[1]
下标(也许是为了阻止静态类型检查?),但我已经将它们保留了下来。string-join()
在SQL Server非常精简的XQuery引擎中不受支持。但这是一个聪明的想法:-)关于[1]
:SQL Server要求在concat()
..@Arkadiusz中使用单例,请继续并提高SQL Server XML功能的投票级别,以符合最新的w3c标准: