【问题标题】:Combine and modify XML in TSQL在 SQL 中合并和修改 XML
【发布时间】:2023-03-02 22:38:01
【问题描述】:

使用SQL Server 2005,是否可以同时合并XML和添加属性?

很遗憾,由于项目限制,我需要一个 SQL Server 2005 解决方案。

考虑以下情况,我需要在一个新的<root> 元素中组合来自多行的 XML...

; WITH [TestTable] AS (
    SELECT 7 AS [PkId], CAST('<data><id>11</id><id>12</id></data>' AS XML) AS [Data]
    UNION ALL
    SELECT 12, CAST('<data><id>22</id></data>' AS XML)
    UNION ALL
    SELECT 43, CAST('<data><id>33</id></data>' AS XML)
)
SELECT (
    SELECT XMLDATA as [*]
    FROM (
        SELECT [Data] AS [*]
        FROM [TestTable]
        FOR XML PATH(''), TYPE
    ) AS DATA(XMLDATA)
    FOR XML PATH('root')
)

这会产生...的所需输出

<root>
  <data><id>11</id><id>12</id></data>
  <data><id>22</id></data>
  <data><id>33</id></data>
</root>

但如果可能的话,我需要做的是向每一行中的 existing 数据元素添加一个属性,该属性具有 PkId 值。所需的输出将如下所示...

<root>
  <data pkid="7"><id>11</id><id>12</id></data>
  <data pkid="12"><id>22</id></data>
  <data pkid="43"><id>33</id></data>
</root>

我的直觉是,如果不使用光标,这将是不可能的,但如果有人知道这样做的方法,我很想听听。


应@MattA的要求,这里是表格中一些随机数据的例子……

[PkId]  [UserId]  [SubmittedDate]      [Data]
1       1         2015-03-24 12:34:56  '<data><id>1</id><id>2</id></data>'
2       1         2015-03-23 09:15:52  '<data><id>3</id></data>'
3       2         2015-03-22 16:01:23  '<data><id>4</id><id>5</id></data>'
4       1         2015-03-21 13:45:34  '<data><id>6</id></data>'

请注意,为了使问题更容易,我声明我需要 PkId 列作为数据的属性。实际上并非如此 - 相反,我需要使用 [SubmittedDate] 列。如果这造成了混乱,我深表歉意。

使用UserId=1 作为过滤器,我想从上面得到的 XML 将是...

<root>
  <data submitteddate="2015-03-24T12:34:56"><id>1</id><id>2</id></data>
  <data submitteddate="2015-03-23T09:15:52"><id>3</id></data>
  <data submitteddate="2015-03-21T13:45:34"><id>6</id></data>
</root>

日期将使用CONVERT 提供的 126 日期格式进行格式化

【问题讨论】:

标签: sql-server xml tsql sql-server-2005


【解决方案1】:

这是给你的快速答案。 XML 确实支持“修改”,但是像这样在小数据集上分解也很有效。

代码

--The existing XML
DECLARE @XML XML = '<root>
  <data><id>11</id></data>
  <data><id>22</id></data>
  <data><id>33</id></data>
</root>'

--XML Shredded Back to a table
;WITH
ShreddedXML AS (
    SELECT
        ID = FieldAlias.value('(id)[1]','int')
    FROM
        @XML.nodes('/root/data') AS TableAlias(FieldAlias)
), ArbitraryPKGenerator AS (
    SELECT  CURRENT_TIMESTAMP AS PKid,
            ID
    FROM    ShreddedXML
)
SELECT  A.PKId AS "@PKid",
        A.ID AS "id"
FROM    ArbitraryPKGenerator AS A
FOR     XML PATH('data'), ROOT('root')

还有 XML

<root>
  <data PKid="2015-03-24T09:44:55.770">
    <id>11</id>
  </data>
  <data PKid="2015-03-24T09:44:55.770">
    <id>22</id>
  </data>
  <data PKid="2015-03-24T09:44:55.770">
    <id>33</id>
  </data>
</root>

【讨论】:

  • 感谢您的回答马特...pkid 是一个简单的示例,但实际上并不是我需要的。将作为属性添加的实际数据将来自表中的 datetime 列......所以我不确定这种方法是否适用于我的具体情况
  • 看看更新。我把 CURRENT_TIMESTAMP 用来展示作为 @PKid 列来源的日期时间。您在该步骤中要做的就是加入源数据并从源表中提取您想要的列。我认为 CURRENT_TIMESTAMP 与 2005 兼容,但 GET_DATE() 也可以。
  • 靠近 Matt - 我真的很感谢您的努力,但该属性的值取自表中还包含 XML 字段的 。所以我需要&lt;data&gt; 让行中的XML 具有pkid 的属性,其中该属性的值是来自同一行的日期时间值。
  • 请添加您希望从中获取日期时间列的表格示例。还请包括与 id 字段相关的值。我可以举一个简单的例子,但我宁愿准确地指出你的要求。
  • 查看更新的问题 - 我希望它更清楚,对于任何混淆,我深表歉意。我试图通过仅说明 pkid 字段来简化问题,目的是在它工作后更改为 submitteddate 字段
猜你喜欢
  • 2012-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多