【问题标题】:Assistance with XML tags协助处理 XML 标签
【发布时间】:2021-11-10 01:49:24
【问题描述】:

我正在处理将输出为 XML 的 SQL 查询 (MS SQL)。我需要一些标签名称相同的标签的帮助,<CustomInteger>。我的输出应该是这样的:

   <CustomIntegers>
      <CustomInteger>
        <FieldID>2701</FieldID>
        <Value>15</Value>
      </CustomInteger>
      <CustomInteger>
        <FieldID>2704</FieldID>
        <Value>28</Value>
      </CustomInteger>
      <CustomInteger>
        <FieldID>2705</FieldID>
        <Value>28</Value>
      </CustomInteger>
    </CustomIntegers>

但我目前得到的是:

<CustomIntegers>
  <CustomInteger>
    <FieldID>2701</FieldID>
    <Value>15</Value>
    <FieldID>2704</FieldID>
    <Value>28</Value>
    <FieldID>2705</FieldID>
    <Value>28</Value>
  </CustomInteger>
</CustomIntegers>

我需要 &lt;FieldID&gt;&lt;Value&gt; 标记在它自己的 &lt;CustomInteger&gt; 标记中。

--创建表

CREATE TABLE [dbo].[Student](
    [TermCode] [varchar](5),
    [StudentID] [varchar](9),
    [RegisteredHours] [decimal](7, 4) NULL,
    [CreditsAttempted] [decimal](7, 4) NULL,
    [CreditsEarned] [decimal](7, 4) NULL
) ON [PRIMARY]

GO

--插入记录

Insert into Student (TermCode, StudentID, RegisteredHours, CreditsAttempted, CreditsEarned)
values ('20211', '123456789', '9.0000', '6.0000', '6.0000')

Insert into Student (TermCode, StudentID, RegisteredHours, CreditsAttempted, CreditsEarned)
values ('20211', '234567890', '15.0000', '28.0000', '28.0000')

Insert into Student (TermCode, StudentID, RegisteredHours, CreditsAttempted, CreditsEarned)
values ('20211', '345678901', '12.0000', '30.0000', '27.0000')

Insert into Student (TermCode, StudentID, RegisteredHours, CreditsAttempted, CreditsEarned)
values ('20211', '456789012', '10.0000', '30.0000', '30.0000')

Insert into Student (TermCode, StudentID, RegisteredHours, CreditsAttempted, CreditsEarned)
values ('20211', '567890123', '12.0000', '32.0000', '29.0000')

--我目前的代码:

select 
'2701' as [CustomInteger/FieldID],
cast(RegisteredHours as int) AS [CustomInteger/Value],
'2704' as [CustomInteger/FieldID],
cast(CreditsAttempted as int) AS [CustomInteger/Value],
'2705' as [CustomInteger/FieldID],
cast(CreditsEarned as int) AS [CustomInteger/Value]
from Student
for xml path('CustomIntegers'), type, elements

任何帮助将不胜感激!

【问题讨论】:

  • 你的数据库是 MS SQL Server 吗?
  • 是的,它是 MS SQL。
  • 提问时,您需要提供minimal reproducible example: (1) DDL 和样本数据填充,即 CREATE 表和 INSERT T-SQL 语句。 (2) 你需要做什么,即逻辑和你的代码尝试在 T-SQL 中实现它。 (3) 期望的输出,基于上面#1 中的样本数据。 (4) 您的 SQL Server 版本 (SELECT @@version;)。
  • 我对在这里发布问题还很陌生。我以为我提供了您提到的所有项目,除了 #4 - SQL Server 版本。
  • 还有 #2 中缺少的逻辑。

标签: sql-server xml tsql xquery


【解决方案1】:

请尝试以下解决方案。

您的输出 XML 似乎应该由一行中的数据组成。

SQL #1

-- DDL and sample data population, start
DECLARE @student TABLE (
    [TermCode] [varchar](5),
    [StudentID] [varchar](9),
    [RegisteredHours] [decimal](7, 4) NULL,
    [CreditsAttempted] [decimal](7, 4) NULL,
    [CreditsEarned] [decimal](7, 4) NULL
);
INSERT INTO @student (TermCode, StudentID, RegisteredHours, CreditsAttempted, CreditsEarned) VALUES 
('20211', '123456789', '9.0000', '6.0000', '6.0000'),
('20211', '234567890', '15.0000', '28.0000', '28.0000'),
('20211', '345678901', '12.0000', '30.0000', '27.0000'),
('20211', '456789012', '10.0000', '30.0000', '30.0000'),
('20211', '567890123', '12.0000', '32.0000', '29.0000');
-- DDL and sample data population, end

SELECT (
    SELECT TRY_CAST(RegisteredHours AS INT) AS RegisteredHours
        , TRY_CAST(CreditsAttempted AS INT) AS CreditsAttempted
        , TRY_CAST(CreditsEarned AS INT) AS CreditsEarned
    FROM @student
    WHERE StudentID = '234567890'
    FOR XML PATH('r'), TYPE, ROOT('root')
).query('<CustomIntegers>
{
    for $x in /root/r/*
    return <CustomInteger>
        <FieldID>
        {
            if (local-name($x)="RegisteredHours") then "2701"
            else if (local-name($x)="CreditsAttempted") then "2704"
            else if (local-name($x)="CreditsEarned") then "2705"
            else ()
        }
        </FieldID>
        <Value>{data($x)}</Value>
    </CustomInteger>
}
</CustomIntegers>');

SQL #2

SELECT '2701' as [CustomInteger/FieldID]
    , TRY_CAST(RegisteredHours as int) AS [CustomInteger/Value], NULL
    , '2704' as [CustomInteger/FieldID]
    , TRY_CAST(CreditsAttempted as int) AS [CustomInteger/Value], NULL
    , '2705' as [CustomInteger/FieldID]
    , TRY_CAST(CreditsEarned as int) AS [CustomInteger/Value]
FROM @Student
--WHERE StudentID = '234567890'
FOR XML PATH('CustomIntegers'), TYPE, ROOT('root');

输出

<CustomIntegers>
  <CustomInteger>
    <FieldID>2701</FieldID>
    <Value>15</Value>
  </CustomInteger>
  <CustomInteger>
    <FieldID>2704</FieldID>
    <Value>28</Value>
  </CustomInteger>
  <CustomInteger>
    <FieldID>2705</FieldID>
    <Value>28</Value>
  </CustomInteger>
</CustomIntegers>

【讨论】:

  • 不明白你为什么在这个问题上如此复杂。我错过了什么吗?
【解决方案2】:

您可以在相关子查询(每行)中对值进行反透视并将它们转换为 XML

SELECT
   (
       SELECT FieldID, Value
       FROM (VALUES
         ('2701',cast(RegisteredHours as int)),
         ('2704',cast(CreditsAttempted as int)),
         ('2705',cast(CreditsEarned as int))
       ) v(FieldID, Value)
       FOR XML PATH('CustomInteger'), TYPE
   ) AS CustomIntegers
FROM Student
FOR XML PATH(''), TYPE;

db<>fiddle

【讨论】:

  • 这是我需要的。非常感谢!
猜你喜欢
  • 2011-02-21
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 2018-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多