在 SQL 中操作标签名称和输出结构 - 第二部分

问题描述 投票:0回答:1

(这是 Yitzhak Khabinsky 很好地回答了Manipulating tag names and output structure in SQL的后续)

我正在尝试以特定的 XML 格式从 Microsoft SQL Server 2016 中提取数据。我可以接近标准的 FOR XML 语句,但没有任何使用 XQuery 的经验——我怀疑这是一个优雅解决方案的核心。

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, FirstName 
VARCHAR(20), MiddleName VARCHAR(20), LastName VARCHAR(20));
INSERT @tbl (FirstName, MiddleName, LastName) VALUES
('Fred', 'A.','Smith'),
('Anna', NULL,'Polack');
-- DDL and sample data population, end

select * from @tbl

;WITH rs(x) AS
(
    SELECT * 
    FROM @tbl
    FOR XML PATH(''), TYPE, ROOT('root')
)
SELECT
 x.query('for $x in /root/*
        return <Answer name="{local-name($x)}">
          <value>{data($x)}</value>
        </Answer>') AS Result 
FROM rs

产生以下内容:

<Answer name="ID">
  <value>1</value>
</Answer>
<Answer name="FirstName">
  <value>Fred</value>
</Answer>
<Answer name="MiddleName">
  <value>A.</value>
</Answer>
<Answer name="LastName">
  <value>Smith</value>
</Answer>
<Answer name="ID">
  <value>2</value>
</Answer>
<Answer name="FirstName">
  <value>Anna</value>
</Answer>
<Answer name="LastName">
  <value>Polack</value>
</Answer>

我想获得更明确的输出枚举,如下所示:

<Answer name="ID_1">
  <value>1</value>
</Answer>
<Answer name="FirstName_1">
  <value>Fred</value>
</Answer>
<Answer name="MiddleName_1">
  <value>A.</value>
</Answer>
<Answer name="LastName_1">
  <value>Smith</value>
</Answer>
<Answer name="ID_2">
  <value>2</value>
</Answer>
<Answer name="FirstName_2">
  <value>Anna</value>
</Answer>
<Answer name="LastName_2">
  <value>Polack</value>
</Answer>

我可以通过使用来破解它:

select STRING_AGG('<Answer name="'+ColKey+'">'+ 
'<value>'+ColValue+'</value></Answer>',' ')
from
(
select  tab.* from @tbl
CROSS APPLY (
VALUES  ('FirstName_'+cast(ID as varchar), FirstName),
('LastName_'+cast(ID as varchar), LastName)
) tab(ColKey, ColValue)
)t

但我确信有一种使用 XQuery 的更优雅的方式

sql sql-server xml xquery
1个回答
1
投票

不需要 string_agg()

例子

Select  [Answer/@name] = concat('ID','_',id)
       ,[Answer/value] = id
       ,null
       ,[Answer/@name] = concat('FirstName','_',id)
       ,[Answer/value] = FirstName
       ,null
       ,[Answer/@name] = concat('MiddleName','_',id)
       ,[Answer/value] = MiddleName
       ,null
       ,[Answer/@name] = concat('LastName','_',id)
       ,[Answer/value] = LastName
 From   @tbl
 For xml path('')

结果

<Answer name="ID_1">
  <value>1</value>
</Answer>
<Answer name="FirstName_1">
  <value>Fred</value>
</Answer>
<Answer name="MiddleName_1">
  <value>A.</value>
</Answer>
<Answer name="LastName_1">
  <value>Smith</value>
</Answer>
<Answer name="ID_2">
  <value>2</value>
</Answer>
<Answer name="FirstName_2">
  <value>Anna</value>
</Answer>
<Answer name="MiddleName_2" />
<Answer name="LastName_2">
  <value>Polack</value>
</Answer>
© www.soinside.com 2019 - 2024. All rights reserved.