在mssql中查询XML节点
我有以下XML记录在mssql中查询XML节点,sql,sql-server,xml,Sql,Sql Server,Xml,我有以下XML记录 <row> <c1>BUSINESS.HOME</c1> <c1 m="2">PAYMENTS.HOME</c1> <c1 m="3">DEPARTMENT.PAGE</c1> <c1 m="4">SECTION.HOME</c1> <c1 m="5">ABOUT.HOME</c1> <c2>Our Busi
<row>
<c1>BUSINESS.HOME</c1>
<c1 m="2">PAYMENTS.HOME</c1>
<c1 m="3">DEPARTMENT.PAGE</c1>
<c1 m="4">SECTION.HOME</c1>
<c1 m="5">ABOUT.HOME</c1>
<c2>Our Business</c2>
<c2 m="1" s="2">Businesul nostru</c2>
<c2 m="2">Payment Services</c2>
<c2 m="2" s="2">Plati</c2>
<c2 m="3">Department Operations</c2>
<c2 m="3" s="2">Departamente</c2>
<c2 m="4">Section Operations</c2>
<c2 m="4" s="2">Sectiuni</c2>
<c2 m="5">ABOUT</c2>
<c2 m="5" s="2">Despre</c2>
<c6>2</c6>
<c10>GB0010001</c10>
<c11>1</c11>
</row>
C1中的每个值和C2中相应的第一个值
我试过这样交叉应用:
select t.p.query('.').value('data(./c2)[1]', 'varchar(max)') c2
from table_name
cross apply XMLRECORD.nodes('(/row/c2)') t(p)
where ID = 'HOME.PAGE'
但不知道如何进一步排除外语并包含C1标记。这有点“难看”,因为必须在NULL
上匹配NULL
,然而,这就是我如何实现您的目标:
DECLARE @XML xml = '
<row>
<c1>BUSINESS.HOME</c1>
<c1 m="2">PAYMENTS.HOME</c1>
<c1 m="3">DEPARTMENT.PAGE</c1>
<c1 m="4">SECTION.HOME</c1>
<c1 m="5">ABOUT.HOME</c1>
<c2>Our Business</c2>
<c2 m="1" s="2">Businesul nostru</c2>
<c2 m="2">Payment Services</c2>
<c2 m="2" s="2">Plati</c2>
<c2 m="3">Department Operations</c2>
<c2 m="3" s="2">Departamente</c2>
<c2 m="4">Section Operations</c2>
<c2 m="4" s="2">Sectiuni</c2>
<c2 m="5">ABOUT</c2>
<c2 m="5" s="2">Despre</c2>
<c6>2</c6>
<c10>GB0010001</c10>
<c11>1</c11>
</row>';
SELECT c1.value('(./text())[1]','varchar(15)') AS [NAME],
c2.value('(./text())[1]','varchar(15)') AS LABEL
FROM @XML.nodes('row/c1') c1(c1)
JOIN @XML.nodes('row/c2') c2(c2) ON (c1.value('@m','int') = c2.value('@m','int') AND c2.value('@s','int') IS NULL)
OR (c1.value('@m','int') IS NULL AND c2.value('@m','int') IS NULL);
DECLARE@XML='XML'
商务之家
家
DEPARTMENT.PAGE
第1节主页
关于家
我们的生意
生意兴隆
支付服务
普拉蒂
部门运作
部门
科室业务
科蒂乌尼
关于
暴君
2.
GB0010001
1.
';
选择c1.value(“(./text())[1]”,“'varchar(15)”作为[NAME],
c2.值('(./text())[1]','varchar(15')作为标签
来自@XML.nodes('row/c1')c1(c1)
连接上的@XML.nodes('row/c2')c2(c2)(c1.value('m','int')=c2.value('m','int'))和c2.value('s','int')为空)
或者(c1.value('@m','int')为空,c2.value('@m','int')为空);
您已经有了一个有效的方法。那很好
我只想添加一个性能更好的替代方案
DECLARE @XML xml = '
<row>
<c1>BUSINESS.HOME</c1>
<c1 m="2">PAYMENTS.HOME</c1>
<c1 m="3">DEPARTMENT.PAGE</c1>
<c1 m="4">SECTION.HOME</c1>
<c1 m="5">ABOUT.HOME</c1>
<c2>Our Business</c2>
<c2 m="1" s="2">Businesul nostru</c2>
<c2 m="2">Payment Services</c2>
<c2 m="2" s="2">Plati</c2>
<c2 m="3">Department Operations</c2>
<c2 m="3" s="2">Departamente</c2>
<c2 m="4">Section Operations</c2>
<c2 m="4" s="2">Sectiuni</c2>
<c2 m="5">ABOUT</c2>
<c2 m="5" s="2">Despre</c2>
<c6>2</c6>
<c10>GB0010001</c10>
<c11>1</c11>
</row>';
简而言之:
- 动态创建一个计数,返回一个从1到n的列表,其中n是
元素的计数(如果您有一个数字表,请改用此表) - 使用Tally的
列,并使用Nmbr
将其引入sql:column()
谓词。XQuery
- 第一个
根据其位置调用.value()
值 - 第二个调用位置x2-1对应的值。如果没有“-1”,您将获得另一种语言李>
- 第一个
s
属性的
元素。在这种情况下,我们不需要计算位置x2-1:
你能告诉我们你的尝试吗?另外,你能解释一下你的逻辑吗。为什么
DEPARTMENT.PAGE
、SECTION.HOME
和ABOUT.HOME
都链接到部门运营
我本希望SECTION.HOME
链接到部门运营
。将您的尝试放在问题中,而不是评论中。您是对的,我更正了结果。我将把这个问题添加到问题中。
DECLARE @XML xml = '
<row>
<c1>BUSINESS.HOME</c1>
<c1 m="2">PAYMENTS.HOME</c1>
<c1 m="3">DEPARTMENT.PAGE</c1>
<c1 m="4">SECTION.HOME</c1>
<c1 m="5">ABOUT.HOME</c1>
<c2>Our Business</c2>
<c2 m="1" s="2">Businesul nostru</c2>
<c2 m="2">Payment Services</c2>
<c2 m="2" s="2">Plati</c2>
<c2 m="3">Department Operations</c2>
<c2 m="3" s="2">Departamente</c2>
<c2 m="4">Section Operations</c2>
<c2 m="4" s="2">Sectiuni</c2>
<c2 m="5">ABOUT</c2>
<c2 m="5" s="2">Despre</c2>
<c6>2</c6>
<c10>GB0010001</c10>
<c11>1</c11>
</row>';
WITH Tally(Nmbr) AS(SELECT TOP(@Xml.value('count(/row/c1)','int')) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM master..spt_values )
SELECT @Xml.value('(/row/c1/text())[sql:column("Nmbr")][1]','nvarchar(250)') AS [NAME]
,@xml.value('(/row/c2/text())[sql:column("Nmbr")*2-1][1]','nvarchar(250)') AS [LABEL]
FROM Tally;
WITH Tally(Nmbr) AS(SELECT TOP(@Xml.value('count(/row/c1)','int')) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM master..spt_values )
SELECT @Xml.value('(/row/c1/text())[sql:column("Nmbr")][1]','nvarchar(250)') AS [NAME]
,@xml.value('(/row/c2[empty(@s)]/text())[sql:column("Nmbr")][1]','nvarchar(250)') AS [LABEL]
FROM Tally